@opennextjs/cloudflare 0.3.10 → 0.4.0
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/README.md +1 -64
- package/dist/api/{get-cloudflare-context.d.ts → cloudflare-context.d.ts} +8 -1
- package/dist/api/cloudflare-context.js +96 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/kvCache.d.ts +0 -5
- package/dist/api/kvCache.js +15 -28
- package/dist/cli/build/build.d.ts +1 -1
- package/dist/cli/build/build.js +2 -12
- package/dist/cli/build/bundle-server.d.ts +4 -5
- package/dist/cli/build/bundle-server.js +32 -36
- package/dist/cli/build/open-next/compile-env-files.d.ts +1 -1
- package/dist/cli/build/open-next/compile-env-files.js +2 -2
- package/dist/cli/build/patches/ast/optional-deps.d.ts +4 -1
- package/dist/cli/build/patches/ast/optional-deps.js +2 -2
- package/dist/cli/build/patches/ast/util.d.ts +15 -4
- package/dist/cli/build/patches/ast/util.js +16 -5
- package/dist/cli/build/patches/ast/vercel-og.d.ts +23 -0
- package/dist/cli/build/patches/ast/vercel-og.js +58 -0
- package/dist/cli/build/patches/ast/vercel-og.spec.d.ts +1 -0
- package/dist/cli/build/patches/ast/vercel-og.spec.js +22 -0
- package/dist/cli/build/patches/investigated/copy-package-cli-files.d.ts +4 -3
- package/dist/cli/build/patches/investigated/copy-package-cli-files.js +8 -5
- package/dist/cli/build/patches/investigated/index.d.ts +1 -0
- package/dist/cli/build/patches/investigated/index.js +1 -0
- package/dist/cli/build/patches/investigated/patch-cache.d.ts +2 -2
- package/dist/cli/build/patches/investigated/patch-cache.js +7 -6
- package/dist/cli/build/patches/investigated/patch-require.d.ts +1 -4
- package/dist/cli/build/patches/investigated/patch-require.js +1 -4
- package/dist/cli/build/patches/investigated/patch-vercel-og-library.d.ts +7 -0
- package/dist/cli/build/patches/investigated/patch-vercel-og-library.js +39 -0
- package/dist/cli/build/patches/investigated/patch-vercel-og-library.spec.d.ts +1 -0
- package/dist/cli/build/patches/investigated/patch-vercel-og-library.spec.js +50 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.d.ts +2 -5
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.js +6 -6
- package/dist/cli/build/patches/to-investigate/inline-eval-manifest.d.ts +2 -2
- package/dist/cli/build/patches/to-investigate/inline-eval-manifest.js +21 -17
- package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.d.ts +2 -2
- package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.js +4 -2
- package/dist/cli/build/patches/to-investigate/inline-next-require.d.ts +2 -2
- package/dist/cli/build/patches/to-investigate/inline-next-require.js +16 -12
- package/dist/cli/build/patches/to-investigate/patch-find-dir.d.ts +3 -6
- package/dist/cli/build/patches/to-investigate/patch-find-dir.js +11 -11
- package/dist/cli/build/patches/to-investigate/patch-read-file.d.ts +3 -3
- package/dist/cli/build/patches/to-investigate/patch-read-file.js +15 -16
- package/dist/cli/build/patches/to-investigate/wrangler-deps.d.ts +2 -2
- package/dist/cli/build/patches/to-investigate/wrangler-deps.js +36 -67
- package/dist/cli/build/utils/create-config-files.d.ts +1 -1
- package/dist/cli/project-options.d.ts +7 -0
- package/dist/cli/project-options.js +1 -0
- package/package.json +4 -4
- package/dist/api/get-cloudflare-context.js +0 -42
- package/dist/cli/config.d.ts +0 -42
- package/dist/cli/config.js +0 -92
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SgNode } from "@ast-grep/napi";
|
|
2
|
+
export declare const vercelOgImportRule = "\nrule:\n pattern: $NODE\n kind: string\n regex: \"next/dist/compiled/@vercel/og/index\\\\.node\\\\.js\"\ninside:\n kind: arguments\n inside:\n kind: call_expression\n stopBy: end\n has:\n field: function\n regex: \"import\"\n\nfix: |-\n \"next/dist/compiled/@vercel/og/index.edge.js\"\n";
|
|
3
|
+
/**
|
|
4
|
+
* Patches Node.js imports for the library to be Edge imports.
|
|
5
|
+
*
|
|
6
|
+
* @param root Root node.
|
|
7
|
+
* @returns Results of applying the rule.
|
|
8
|
+
*/
|
|
9
|
+
export declare function patchVercelOgImport(root: SgNode): {
|
|
10
|
+
edits: import("@ast-grep/napi").Edit[];
|
|
11
|
+
matches: SgNode<import("@ast-grep/napi/types/staticTypes.js").TypesMap, import("@ast-grep/napi/types/staticTypes.js").Kinds<import("@ast-grep/napi/types/staticTypes.js").TypesMap>>[];
|
|
12
|
+
};
|
|
13
|
+
export declare const vercelOgFallbackFontRule = "\nrule:\n kind: variable_declaration\n all:\n - has:\n kind: variable_declarator\n has:\n kind: identifier\n regex: ^fallbackFont$\n - has:\n kind: call_expression\n pattern: fetch(new URL(\"$PATH\", $$$REST))\n stopBy: end\n\nfix: |-\n async function getFallbackFont() {\n // .bin is used so that a loader does not need to be configured for .ttf files\n return (await import(\"$PATH.bin\")).default;\n }\n\n var fallbackFont = getFallbackFont();\n";
|
|
14
|
+
/**
|
|
15
|
+
* Patches the default font fetching to use a .bin import.
|
|
16
|
+
*
|
|
17
|
+
* @param root Root node.
|
|
18
|
+
* @returns Results of applying the rule.
|
|
19
|
+
*/
|
|
20
|
+
export declare function patchVercelOgFallbackFont(root: SgNode): {
|
|
21
|
+
edits: import("@ast-grep/napi").Edit[];
|
|
22
|
+
matches: SgNode<import("@ast-grep/napi/types/staticTypes.js").TypesMap, import("@ast-grep/napi/types/staticTypes.js").Kinds<import("@ast-grep/napi/types/staticTypes.js").TypesMap>>[];
|
|
23
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { applyRule } from "./util.js";
|
|
2
|
+
export const vercelOgImportRule = `
|
|
3
|
+
rule:
|
|
4
|
+
pattern: $NODE
|
|
5
|
+
kind: string
|
|
6
|
+
regex: "next/dist/compiled/@vercel/og/index\\\\.node\\\\.js"
|
|
7
|
+
inside:
|
|
8
|
+
kind: arguments
|
|
9
|
+
inside:
|
|
10
|
+
kind: call_expression
|
|
11
|
+
stopBy: end
|
|
12
|
+
has:
|
|
13
|
+
field: function
|
|
14
|
+
regex: "import"
|
|
15
|
+
|
|
16
|
+
fix: |-
|
|
17
|
+
"next/dist/compiled/@vercel/og/index.edge.js"
|
|
18
|
+
`;
|
|
19
|
+
/**
|
|
20
|
+
* Patches Node.js imports for the library to be Edge imports.
|
|
21
|
+
*
|
|
22
|
+
* @param root Root node.
|
|
23
|
+
* @returns Results of applying the rule.
|
|
24
|
+
*/
|
|
25
|
+
export function patchVercelOgImport(root) {
|
|
26
|
+
return applyRule(vercelOgImportRule, root);
|
|
27
|
+
}
|
|
28
|
+
export const vercelOgFallbackFontRule = `
|
|
29
|
+
rule:
|
|
30
|
+
kind: variable_declaration
|
|
31
|
+
all:
|
|
32
|
+
- has:
|
|
33
|
+
kind: variable_declarator
|
|
34
|
+
has:
|
|
35
|
+
kind: identifier
|
|
36
|
+
regex: ^fallbackFont$
|
|
37
|
+
- has:
|
|
38
|
+
kind: call_expression
|
|
39
|
+
pattern: fetch(new URL("$PATH", $$$REST))
|
|
40
|
+
stopBy: end
|
|
41
|
+
|
|
42
|
+
fix: |-
|
|
43
|
+
async function getFallbackFont() {
|
|
44
|
+
// .bin is used so that a loader does not need to be configured for .ttf files
|
|
45
|
+
return (await import("$PATH.bin")).default;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var fallbackFont = getFallbackFont();
|
|
49
|
+
`;
|
|
50
|
+
/**
|
|
51
|
+
* Patches the default font fetching to use a .bin import.
|
|
52
|
+
*
|
|
53
|
+
* @param root Root node.
|
|
54
|
+
* @returns Results of applying the rule.
|
|
55
|
+
*/
|
|
56
|
+
export function patchVercelOgFallbackFont(root) {
|
|
57
|
+
return applyRule(vercelOgFallbackFontRule, root);
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { patchCode } from "./util";
|
|
3
|
+
import { vercelOgFallbackFontRule, vercelOgImportRule } from "./vercel-og";
|
|
4
|
+
describe("vercelOgImportRule", () => {
|
|
5
|
+
it("should rewrite a node import to an edge import", () => {
|
|
6
|
+
const code = `e.exports=import("next/dist/compiled/@vercel/og/index.node.js")`;
|
|
7
|
+
expect(patchCode(code, vercelOgImportRule)).toMatchInlineSnapshot(`"e.exports=import("next/dist/compiled/@vercel/og/index.edge.js")"`);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
describe("vercelOgFallbackFontRule", () => {
|
|
11
|
+
it("should replace a fetch call for a font with an import", () => {
|
|
12
|
+
const code = `var fallbackFont = fetch(new URL("./noto-sans-v27-latin-regular.ttf", import.meta.url)).then((res) => res.arrayBuffer());`;
|
|
13
|
+
expect(patchCode(code, vercelOgFallbackFontRule)).toMatchInlineSnapshot(`
|
|
14
|
+
"async function getFallbackFont() {
|
|
15
|
+
// .bin is used so that a loader does not need to be configured for .ttf files
|
|
16
|
+
return (await import("./noto-sans-v27-latin-regular.ttf.bin")).default;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var fallbackFont = getFallbackFont();"
|
|
20
|
+
`);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
-
import { Config } from "../../../config.js";
|
|
3
2
|
/**
|
|
4
|
-
* Copies
|
|
3
|
+
* Copies
|
|
4
|
+
* - the template files present in the cloudflare adapter package to `.open-next/cloudflare-templates`
|
|
5
|
+
* - `worker.js` to `.open-next/`
|
|
5
6
|
*/
|
|
6
|
-
export declare function copyPackageCliFiles(packageDistDir: string,
|
|
7
|
+
export declare function copyPackageCliFiles(packageDistDir: string, buildOpts: BuildOptions): void;
|
|
@@ -2,12 +2,15 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { getOutputWorkerPath } from "../../bundle-server.js";
|
|
4
4
|
/**
|
|
5
|
-
* Copies
|
|
5
|
+
* Copies
|
|
6
|
+
* - the template files present in the cloudflare adapter package to `.open-next/cloudflare-templates`
|
|
7
|
+
* - `worker.js` to `.open-next/`
|
|
6
8
|
*/
|
|
7
|
-
export function copyPackageCliFiles(packageDistDir,
|
|
9
|
+
export function copyPackageCliFiles(packageDistDir, buildOpts) {
|
|
8
10
|
console.log("# copyPackageTemplateFiles");
|
|
9
|
-
const sourceDir = path.join(packageDistDir, "cli");
|
|
10
|
-
const destinationDir = path.join(
|
|
11
|
+
const sourceDir = path.join(packageDistDir, "cli/templates");
|
|
12
|
+
const destinationDir = path.join(buildOpts.outputDir, "cloudflare-templates");
|
|
13
|
+
fs.mkdirSync(destinationDir, { recursive: true });
|
|
11
14
|
fs.cpSync(sourceDir, destinationDir, { recursive: true });
|
|
12
|
-
fs.copyFileSync(path.join(packageDistDir, "cli
|
|
15
|
+
fs.copyFileSync(path.join(packageDistDir, "cli/templates/worker.js"), getOutputWorkerPath(buildOpts));
|
|
13
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
3
|
* Sets up the OpenNext cache handler in a Next.js build.
|
|
4
4
|
*
|
|
@@ -10,4 +10,4 @@ import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
|
10
10
|
* build-time. Therefore, we have to manually override the default way that the cache handler is
|
|
11
11
|
* instantiated with a dynamic require that uses a string literal for the path.
|
|
12
12
|
*/
|
|
13
|
-
export declare function patchCache(code: string,
|
|
13
|
+
export declare function patchCache(code: string, buildOpts: BuildOptions): Promise<string>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
2
3
|
import { normalizePath } from "../../utils/index.js";
|
|
3
4
|
/**
|
|
4
5
|
* Sets up the OpenNext cache handler in a Next.js build.
|
|
@@ -11,13 +12,13 @@ import { normalizePath } from "../../utils/index.js";
|
|
|
11
12
|
* build-time. Therefore, we have to manually override the default way that the cache handler is
|
|
12
13
|
* instantiated with a dynamic require that uses a string literal for the path.
|
|
13
14
|
*/
|
|
14
|
-
export async function patchCache(code,
|
|
15
|
-
const {
|
|
15
|
+
export async function patchCache(code, buildOpts) {
|
|
16
|
+
const { outputDir } = buildOpts;
|
|
16
17
|
// TODO: switch to cache.mjs
|
|
17
|
-
const outputPath = path.join(outputDir, "server-functions
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
18
|
+
const outputPath = path.join(outputDir, "server-functions/default");
|
|
19
|
+
const cacheFile = path.join(outputPath, getPackagePath(buildOpts), "cache.cjs");
|
|
20
|
+
return code.replace("const { cacheHandler } = this.nextConfig;", `
|
|
21
|
+
const cacheHandler = null;
|
|
21
22
|
CacheHandler = require('${normalizePath(cacheFile)}').default;
|
|
22
23
|
`);
|
|
23
24
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* See https://github.com/evanw/esbuild/issues/1921 and linked issues
|
|
4
|
-
* Some of the solutions are based on `module.createRequire()` not implemented in workerd.
|
|
5
|
-
* James on Aug 29: `module.createRequire()` is planned.
|
|
2
|
+
* Replaces webpack `__require` with actual `require`
|
|
6
3
|
*/
|
|
7
4
|
export declare function patchRequire(code: string): string;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* See https://github.com/evanw/esbuild/issues/1921 and linked issues
|
|
4
|
-
* Some of the solutions are based on `module.createRequire()` not implemented in workerd.
|
|
5
|
-
* James on Aug 29: `module.createRequire()` is planned.
|
|
2
|
+
* Replaces webpack `__require` with actual `require`
|
|
6
3
|
*/
|
|
7
4
|
export function patchRequire(code) {
|
|
8
5
|
return code.replace(/__require\d?\(/g, "require(").replace(/__require\d?\./g, "require.");
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
/**
|
|
3
|
+
* Patches the usage of @vercel/og to be compatible with Cloudflare Workers.
|
|
4
|
+
*
|
|
5
|
+
* @param buildOpts Build options.
|
|
6
|
+
*/
|
|
7
|
+
export declare function patchVercelOgLibrary(buildOpts: BuildOptions): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
4
|
+
import { globSync } from "glob";
|
|
5
|
+
import { parseFile } from "../ast/util.js";
|
|
6
|
+
import { patchVercelOgFallbackFont, patchVercelOgImport } from "../ast/vercel-og.js";
|
|
7
|
+
/**
|
|
8
|
+
* Patches the usage of @vercel/og to be compatible with Cloudflare Workers.
|
|
9
|
+
*
|
|
10
|
+
* @param buildOpts Build options.
|
|
11
|
+
*/
|
|
12
|
+
export function patchVercelOgLibrary(buildOpts) {
|
|
13
|
+
const { appBuildOutputPath, outputDir } = buildOpts;
|
|
14
|
+
const packagePath = path.join(outputDir, "server-functions/default", getPackagePath(buildOpts));
|
|
15
|
+
for (const traceInfoPath of globSync(path.join(appBuildOutputPath, ".next/server/**/*.nft.json"))) {
|
|
16
|
+
const traceInfo = JSON.parse(readFileSync(traceInfoPath, { encoding: "utf8" }));
|
|
17
|
+
const tracedNodePath = traceInfo.files.find((p) => p.endsWith("@vercel/og/index.node.js"));
|
|
18
|
+
if (!tracedNodePath)
|
|
19
|
+
continue;
|
|
20
|
+
const outputDir = path.join(packagePath, "node_modules/next/dist/compiled/@vercel/og");
|
|
21
|
+
const outputEdgePath = path.join(outputDir, "index.edge.js");
|
|
22
|
+
// Ensure the edge version is available in the OpenNext node_modules.
|
|
23
|
+
if (!existsSync(outputEdgePath)) {
|
|
24
|
+
const tracedEdgePath = path.join(path.dirname(traceInfoPath), tracedNodePath.replace("index.node.js", "index.edge.js"));
|
|
25
|
+
copyFileSync(tracedEdgePath, outputEdgePath);
|
|
26
|
+
// Change font fetches in the library to use imports.
|
|
27
|
+
const node = parseFile(outputEdgePath);
|
|
28
|
+
const { edits, matches } = patchVercelOgFallbackFont(node);
|
|
29
|
+
writeFileSync(outputEdgePath, node.commitEdits(edits));
|
|
30
|
+
const fontFileName = matches[0].getMatch("PATH").text();
|
|
31
|
+
renameSync(path.join(outputDir, fontFileName), path.join(outputDir, `${fontFileName}.bin`));
|
|
32
|
+
}
|
|
33
|
+
// Change node imports for the library to edge imports.
|
|
34
|
+
const routeFilePath = traceInfoPath.replace(appBuildOutputPath, packagePath).replace(".nft.json", "");
|
|
35
|
+
const node = parseFile(routeFilePath);
|
|
36
|
+
const { edits } = patchVercelOgImport(node);
|
|
37
|
+
writeFileSync(routeFilePath, node.commitEdits(edits));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import mockFs from "mock-fs";
|
|
4
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
5
|
+
import { patchVercelOgLibrary } from "./patch-vercel-og-library";
|
|
6
|
+
const nodeModulesVercelOgDir = "node_modules/.pnpm/next@14.2.11/node_modules/next/dist/compiled/@vercel/og";
|
|
7
|
+
const nextServerOgNftPath = "examples/api/.next/server/app/og/route.js.nft.json";
|
|
8
|
+
const openNextFunctionDir = "examples/api/.open-next/server-functions/default/examples/api";
|
|
9
|
+
const openNextOgRoutePath = path.join(openNextFunctionDir, ".next/server/app/og/route.js");
|
|
10
|
+
const openNextVercelOgDir = path.join(openNextFunctionDir, "node_modules/next/dist/compiled/@vercel/og");
|
|
11
|
+
const buildOpts = {
|
|
12
|
+
appBuildOutputPath: "examples/api",
|
|
13
|
+
monorepoRoot: "",
|
|
14
|
+
outputDir: "examples/api/.open-next",
|
|
15
|
+
};
|
|
16
|
+
describe("patchVercelOgLibrary", () => {
|
|
17
|
+
beforeAll(() => {
|
|
18
|
+
mockFs();
|
|
19
|
+
mkdirSync(nodeModulesVercelOgDir, { recursive: true });
|
|
20
|
+
mkdirSync(path.dirname(nextServerOgNftPath), { recursive: true });
|
|
21
|
+
mkdirSync(path.dirname(openNextOgRoutePath), { recursive: true });
|
|
22
|
+
mkdirSync(openNextVercelOgDir, { recursive: true });
|
|
23
|
+
writeFileSync(nextServerOgNftPath, JSON.stringify({ version: 1, files: [`../../../../../../${nodeModulesVercelOgDir}/index.node.js`] }));
|
|
24
|
+
writeFileSync(path.join(nodeModulesVercelOgDir, "index.edge.js"), `var fallbackFont = fetch(new URL("./noto-sans-v27-latin-regular.ttf", import.meta.url)).then((res) => res.arrayBuffer());`);
|
|
25
|
+
writeFileSync(openNextOgRoutePath, `e.exports=import("next/dist/compiled/@vercel/og/index.node.js")`);
|
|
26
|
+
writeFileSync(path.join(openNextVercelOgDir, "index.node.js"), "");
|
|
27
|
+
writeFileSync(path.join(openNextVercelOgDir, "noto-sans-v27-latin-regular.ttf"), "");
|
|
28
|
+
});
|
|
29
|
+
afterAll(() => mockFs.restore());
|
|
30
|
+
it("should patch the open-next files correctly", () => {
|
|
31
|
+
patchVercelOgLibrary(buildOpts);
|
|
32
|
+
expect(readdirSync(openNextVercelOgDir)).toMatchInlineSnapshot(`
|
|
33
|
+
[
|
|
34
|
+
"index.edge.js",
|
|
35
|
+
"index.node.js",
|
|
36
|
+
"noto-sans-v27-latin-regular.ttf.bin",
|
|
37
|
+
]
|
|
38
|
+
`);
|
|
39
|
+
expect(readFileSync(path.join(openNextVercelOgDir, "index.edge.js"), { encoding: "utf-8" }))
|
|
40
|
+
.toMatchInlineSnapshot(`
|
|
41
|
+
"async function getFallbackFont() {
|
|
42
|
+
// .bin is used so that a loader does not need to be configured for .ttf files
|
|
43
|
+
return (await import("./noto-sans-v27-latin-regular.ttf.bin")).default;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var fallbackFont = getFallbackFont();"
|
|
47
|
+
`);
|
|
48
|
+
expect(readFileSync(openNextOgRoutePath, { encoding: "utf-8" })).toMatchInlineSnapshot(`"e.exports=import("next/dist/compiled/@vercel/og/index.edge.js")"`);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
3
|
* Fixes the webpack-runtime.js file by removing its webpack dynamic requires.
|
|
4
|
-
*
|
|
5
|
-
* This hack is particularly bad as it indicates that files inside the output directory still get a hold of files from the outside: `${nextjsAppPaths.standaloneAppServerDir}/webpack-runtime.js`
|
|
6
|
-
* so this shows that not everything that's needed to deploy the application is in the output directory...
|
|
7
4
|
*/
|
|
8
|
-
export declare function updateWebpackChunksFile(
|
|
5
|
+
export declare function updateWebpackChunksFile(buildOpts: BuildOptions): Promise<void>;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
3
4
|
import { getUpdatedWebpackChunksFileContent } from "./get-updated-webpack-chunks-file-content.js";
|
|
4
5
|
/**
|
|
5
6
|
* Fixes the webpack-runtime.js file by removing its webpack dynamic requires.
|
|
6
|
-
*
|
|
7
|
-
* This hack is particularly bad as it indicates that files inside the output directory still get a hold of files from the outside: `${nextjsAppPaths.standaloneAppServerDir}/webpack-runtime.js`
|
|
8
|
-
* so this shows that not everything that's needed to deploy the application is in the output directory...
|
|
9
7
|
*/
|
|
10
|
-
export async function updateWebpackChunksFile(
|
|
8
|
+
export async function updateWebpackChunksFile(buildOpts) {
|
|
11
9
|
console.log("# updateWebpackChunksFile");
|
|
12
|
-
const
|
|
10
|
+
const { outputDir } = buildOpts;
|
|
11
|
+
const dotNextServerDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
12
|
+
const webpackRuntimeFile = join(dotNextServerDir, "webpack-runtime.js");
|
|
13
13
|
const fileContent = readFileSync(webpackRuntimeFile, "utf-8");
|
|
14
|
-
const chunks = readdirSync(join(
|
|
14
|
+
const chunks = readdirSync(join(dotNextServerDir, "chunks"))
|
|
15
15
|
.filter((chunk) => /^\d+\.js$/.test(chunk))
|
|
16
16
|
.map((chunk) => {
|
|
17
17
|
console.log(` - chunk ${chunk}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
3
|
* `evalManifest` relies on readFileSync so we need to patch the function so that it instead returns the content of the manifest files
|
|
4
4
|
* which are known at build time
|
|
@@ -6,4 +6,4 @@ import { Config } from "../../../config.js";
|
|
|
6
6
|
* Note: we could/should probably just patch readFileSync here or something, but here the issue is that after the readFileSync call
|
|
7
7
|
* there is a vm `runInNewContext` call which we also don't support (source: https://github.com/vercel/next.js/blob/b1e32c5d1f/packages/next/src/server/load-manifest.ts#L88)
|
|
8
8
|
*/
|
|
9
|
-
export declare function inlineEvalManifest(code: string,
|
|
9
|
+
export declare function inlineEvalManifest(code: string, buildOpts: BuildOptions): string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { join,
|
|
1
|
+
import { join, relative } from "node:path";
|
|
2
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
2
3
|
import { globSync } from "glob";
|
|
3
4
|
import { normalizePath } from "../../utils/index.js";
|
|
4
5
|
/**
|
|
@@ -8,24 +9,27 @@ import { normalizePath } from "../../utils/index.js";
|
|
|
8
9
|
* Note: we could/should probably just patch readFileSync here or something, but here the issue is that after the readFileSync call
|
|
9
10
|
* there is a vm `runInNewContext` call which we also don't support (source: https://github.com/vercel/next.js/blob/b1e32c5d1f/packages/next/src/server/load-manifest.ts#L88)
|
|
10
11
|
*/
|
|
11
|
-
export function inlineEvalManifest(code,
|
|
12
|
-
const
|
|
12
|
+
export function inlineEvalManifest(code, buildOpts) {
|
|
13
|
+
const { outputDir } = buildOpts;
|
|
14
|
+
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
|
|
15
|
+
const appDir = join(baseDir, "server/app");
|
|
16
|
+
const manifests = globSync(join(baseDir, "**/*_client-reference-manifest.js"));
|
|
13
17
|
return code.replace(/function evalManifest\((.+?), .+?\) {/, `$&
|
|
14
|
-
${
|
|
15
|
-
.map((
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
18
|
+
${manifests
|
|
19
|
+
.map((manifest) => {
|
|
20
|
+
const endsWith = normalizePath(relative(baseDir, manifest));
|
|
21
|
+
const key = normalizePath("/" + relative(appDir, manifest)).replace("_client-reference-manifest.js", "");
|
|
22
|
+
return `
|
|
23
|
+
if ($1.endsWith("${endsWith}")) {
|
|
24
|
+
require(${JSON.stringify(manifest)});
|
|
25
|
+
return {
|
|
26
|
+
__RSC_MANIFEST: {
|
|
27
|
+
"${key}": globalThis.__RSC_MANIFEST["${key}"],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
27
30
|
}
|
|
28
|
-
|
|
31
|
+
`;
|
|
32
|
+
})
|
|
29
33
|
.join("\n")}
|
|
30
34
|
throw new Error("Unknown evalManifest: " + $1);
|
|
31
35
|
`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
3
|
* Inlines the middleware manifest from the build output to prevent a dynamic require statement
|
|
4
4
|
* as they result in runtime failures.
|
|
5
5
|
*/
|
|
6
|
-
export declare function inlineMiddlewareManifestRequire(code: string,
|
|
6
|
+
export declare function inlineMiddlewareManifestRequire(code: string, buildOpts: BuildOptions): string;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
3
4
|
/**
|
|
4
5
|
* Inlines the middleware manifest from the build output to prevent a dynamic require statement
|
|
5
6
|
* as they result in runtime failures.
|
|
6
7
|
*/
|
|
7
|
-
export function inlineMiddlewareManifestRequire(code,
|
|
8
|
-
const
|
|
8
|
+
export function inlineMiddlewareManifestRequire(code, buildOpts) {
|
|
9
|
+
const { outputDir } = buildOpts;
|
|
10
|
+
const middlewareManifestPath = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server/middleware-manifest.json");
|
|
9
11
|
const middlewareManifest = existsSync(middlewareManifestPath)
|
|
10
12
|
? JSON.parse(readFileSync(middlewareManifestPath, "utf-8"))
|
|
11
13
|
: {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
3
|
* The following avoid various Next.js specific files `require`d at runtime since we can just read
|
|
4
4
|
* and inline their content during build time
|
|
5
5
|
*/
|
|
6
|
-
export declare function inlineNextRequire(code: string,
|
|
6
|
+
export declare function inlineNextRequire(code: string, buildOpts: BuildOptions): string;
|
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
3
4
|
/**
|
|
4
5
|
* The following avoid various Next.js specific files `require`d at runtime since we can just read
|
|
5
6
|
* and inline their content during build time
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
8
|
+
// TODO(vicb): __NEXT_PRIVATE_RUNTIME_TYPE is not handled by this patch
|
|
9
|
+
export function inlineNextRequire(code, buildOpts) {
|
|
10
|
+
const { outputDir } = buildOpts;
|
|
11
|
+
const serverDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
12
|
+
const pagesManifestFile = join(serverDir, "pages-manifest.json");
|
|
13
|
+
const appPathsManifestFile = join(serverDir, "app-paths-manifest.json");
|
|
14
|
+
const pagesManifests = existsSync(pagesManifestFile)
|
|
15
|
+
? Object.values(JSON.parse(readFileSync(pagesManifestFile, "utf-8")))
|
|
12
16
|
: [];
|
|
13
|
-
const
|
|
14
|
-
? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8")))
|
|
17
|
+
const appPathsManifests = existsSync(appPathsManifestFile)
|
|
18
|
+
? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8")))
|
|
15
19
|
: [];
|
|
16
|
-
const
|
|
17
|
-
const htmlPages =
|
|
18
|
-
const pageModules =
|
|
20
|
+
const manifests = pagesManifests.concat(appPathsManifests);
|
|
21
|
+
const htmlPages = manifests.filter((file) => file.endsWith(".html"));
|
|
22
|
+
const pageModules = manifests.filter((file) => file.endsWith(".js"));
|
|
19
23
|
return code.replace(/const pagePath = getPagePath\(.+?\);/, `$&
|
|
20
24
|
${htmlPages
|
|
21
25
|
.map((htmlPage) => `
|
|
22
26
|
if (pagePath.endsWith("${htmlPage}")) {
|
|
23
|
-
return ${JSON.stringify(readFileSync(join(
|
|
27
|
+
return ${JSON.stringify(readFileSync(join(serverDir, htmlPage), "utf-8"))};
|
|
24
28
|
}
|
|
25
29
|
`)
|
|
26
30
|
.join("\n")}
|
|
27
31
|
${pageModules
|
|
28
32
|
.map((module) => `
|
|
29
33
|
if (pagePath.endsWith("${module}")) {
|
|
30
|
-
return require(${JSON.stringify(join(
|
|
34
|
+
return require(${JSON.stringify(join(serverDir, module))});
|
|
31
35
|
}
|
|
32
36
|
`)
|
|
33
37
|
.join("\n")}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* (source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/lib/find-pages-dir.ts#L4-L13)
|
|
5
|
-
* (usage source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/server/next-server.ts#L450-L451)
|
|
6
|
-
* Note: `findDir` uses `fs.existsSync` under the hood, so patching that should be enough to make this work
|
|
3
|
+
* Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
|
|
7
4
|
*/
|
|
8
|
-
export declare function patchFindDir(code: string,
|
|
5
|
+
export declare function patchFindDir(code: string, buildOpts: BuildOptions): string;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
* (source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/lib/find-pages-dir.ts#L4-L13)
|
|
6
|
-
* (usage source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/server/next-server.ts#L450-L451)
|
|
7
|
-
* Note: `findDir` uses `fs.existsSync` under the hood, so patching that should be enough to make this work
|
|
5
|
+
* Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
|
|
8
6
|
*/
|
|
9
|
-
export function patchFindDir(code,
|
|
7
|
+
export function patchFindDir(code, buildOpts) {
|
|
8
|
+
const { outputDir } = buildOpts;
|
|
9
|
+
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
10
10
|
return code.replace(/function findDir\((?<dir>dir\d*), (?<name>name\d*)\) {/, `function findDir($dir, $name) {
|
|
11
11
|
if ($dir.endsWith(".next/server")) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
if ($name === "app") {
|
|
13
|
+
return ${existsSync(`${join(baseDir, "app")}`)};
|
|
14
|
+
}
|
|
15
|
+
if ($name === "pages") {
|
|
16
|
+
return ${existsSync(`${join(baseDir, "pages")}`)};
|
|
17
|
+
}
|
|
18
18
|
}
|
|
19
19
|
throw new Error("Unknown findDir call: " + $dir + " " + $name);
|
|
20
20
|
`);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function patchBuildId(code: string,
|
|
3
|
-
export declare function patchLoadManifest(code: string,
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
export declare function patchBuildId(code: string, buildOpts: BuildOptions): string;
|
|
3
|
+
export declare function patchLoadManifest(code: string, buildOpts: BuildOptions): string;
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { join,
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { getBuildId, getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
3
4
|
import { globSync } from "glob";
|
|
4
5
|
import { normalizePath } from "../../utils/index.js";
|
|
5
|
-
export function patchBuildId(code,
|
|
6
|
-
// The
|
|
7
|
-
// so we add an early return to the `getBuildId` function so that the `readyFileSync` is never encountered
|
|
8
|
-
// (source: https://github.com/vercel/next.js/blob/15aeb92efb34c09a36/packages/next/src/server/next-server.ts#L438-L451)
|
|
9
|
-
// Note: we could/should probably just patch readFileSync here or something!
|
|
6
|
+
export function patchBuildId(code, buildOpts) {
|
|
7
|
+
// The Next code gets the buildId from the filesystem so we hardcode the value at build time.
|
|
10
8
|
return code.replace("getBuildId() {", `getBuildId() {
|
|
11
|
-
return ${JSON.stringify(
|
|
9
|
+
return ${JSON.stringify(getBuildId(buildOpts))};
|
|
12
10
|
`);
|
|
13
11
|
}
|
|
14
|
-
export function patchLoadManifest(code,
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
12
|
+
export function patchLoadManifest(code, buildOpts) {
|
|
13
|
+
// Inline manifest that Next would otherwise retrieve from the file system.
|
|
14
|
+
const { outputDir } = buildOpts;
|
|
15
|
+
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
|
|
16
|
+
const dotNextDir = join(baseDir, ".next");
|
|
17
|
+
const manifests = globSync(join(dotNextDir, "**/*-manifest.json"));
|
|
19
18
|
return code.replace(/function loadManifest\((.+?), .+?\) {/, `$&
|
|
20
|
-
${
|
|
21
|
-
.map((
|
|
22
|
-
if ($1.endsWith("${
|
|
23
|
-
return ${readFileSync(
|
|
19
|
+
${manifests
|
|
20
|
+
.map((manifest) => `
|
|
21
|
+
if ($1.endsWith("${normalizePath("/" + relative(dotNextDir, manifest))}")) {
|
|
22
|
+
return ${readFileSync(manifest, "utf-8")};
|
|
24
23
|
}
|
|
25
24
|
`)
|
|
26
25
|
.join("\n")}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function patchWranglerDeps(
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
export declare function patchWranglerDeps(buildOpts: BuildOptions): void;
|