@opennextjs/cloudflare 0.2.0 → 0.3.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 +48 -38
- package/dist/api/{get-cloudflare-context.d.mts → get-cloudflare-context.d.ts} +4 -4
- package/dist/api/get-cloudflare-context.js +39 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/kvCache.d.ts +27 -0
- package/dist/api/kvCache.js +121 -0
- package/dist/cli/args.d.ts +5 -0
- package/dist/cli/args.js +48 -0
- package/dist/cli/build/bundle-server.d.ts +6 -0
- package/dist/cli/build/bundle-server.js +188 -0
- package/dist/cli/build/index.d.ts +9 -0
- package/dist/cli/build/index.js +123 -0
- package/dist/cli/build/open-next/compile-env-files.d.ts +5 -0
- package/dist/cli/build/open-next/compile-env-files.js +9 -0
- package/dist/cli/build/open-next/copyCacheAssets.d.ts +2 -0
- package/dist/cli/build/open-next/copyCacheAssets.js +10 -0
- package/dist/cli/build/open-next/createServerBundle.d.ts +2 -0
- package/dist/cli/build/open-next/createServerBundle.js +216 -0
- package/dist/cli/build/patches/index.d.ts +2 -0
- package/dist/cli/build/patches/index.js +2 -0
- package/dist/cli/build/patches/investigated/copy-package-cli-files.d.ts +6 -0
- package/dist/cli/build/patches/investigated/copy-package-cli-files.js +12 -0
- package/dist/cli/build/patches/investigated/index.d.ts +4 -0
- package/dist/cli/build/patches/investigated/index.js +4 -0
- package/dist/cli/build/patches/investigated/patch-cache.d.ts +13 -0
- package/dist/cli/build/patches/investigated/patch-cache.js +22 -0
- package/dist/cli/build/patches/investigated/patch-require.d.ts +7 -0
- package/dist/cli/build/patches/investigated/patch-require.js +9 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.d.ts +13 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.js +82 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.test.d.ts +1 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.test.js +20 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-file-content-with-updated-webpack-f-require-code.d.ts +19 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-file-content-with-updated-webpack-f-require-code.js +76 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-file-content-with-updated-webpack-f-require-code.test.d.ts +1 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-file-content-with-updated-webpack-f-require-code.test.js +23 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-updated-webpack-chunks-file-content.d.ts +14 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-updated-webpack-chunks-file-content.js +22 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-updated-webpack-chunks-file-content.test.d.ts +1 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/get-updated-webpack-chunks-file-content.test.js +15 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.d.ts +8 -0
- package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.js +22 -0
- package/dist/cli/build/patches/to-investigate/index.d.ts +8 -0
- package/dist/cli/build/patches/to-investigate/index.js +8 -0
- package/dist/cli/build/patches/to-investigate/inline-eval-manifest.d.ts +9 -0
- package/dist/cli/build/patches/to-investigate/inline-eval-manifest.js +32 -0
- package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.d.ts +6 -0
- package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.js +13 -0
- package/dist/cli/build/patches/to-investigate/inline-next-require.d.ts +6 -0
- package/dist/cli/build/patches/to-investigate/inline-next-require.js +36 -0
- package/dist/cli/build/patches/to-investigate/patch-exception-bubbling.d.ts +7 -0
- package/dist/cli/build/patches/to-investigate/patch-exception-bubbling.js +9 -0
- package/dist/cli/build/patches/to-investigate/patch-find-dir.d.ts +8 -0
- package/dist/cli/build/patches/to-investigate/patch-find-dir.js +21 -0
- package/dist/cli/build/patches/to-investigate/patch-load-instrumentation-module.d.ts +14 -0
- package/dist/cli/build/patches/to-investigate/patch-load-instrumentation-module.js +34 -0
- package/dist/cli/build/patches/to-investigate/patch-read-file.d.ts +3 -0
- package/dist/cli/build/patches/to-investigate/patch-read-file.js +29 -0
- package/dist/cli/build/patches/to-investigate/wrangler-deps.d.ts +2 -0
- package/dist/cli/build/patches/to-investigate/wrangler-deps.js +54 -0
- package/dist/cli/build/utils/extract-project-env-vars.d.ts +18 -0
- package/dist/cli/build/utils/extract-project-env-vars.js +32 -0
- package/dist/cli/build/utils/extract-project-env-vars.spec.d.ts +1 -0
- package/dist/cli/build/utils/extract-project-env-vars.spec.js +57 -0
- package/dist/cli/build/utils/index.d.ts +3 -0
- package/dist/cli/build/utils/index.js +3 -0
- package/dist/cli/build/utils/normalize-path.d.ts +1 -0
- package/dist/cli/build/utils/normalize-path.js +4 -0
- package/dist/cli/build/utils/read-paths-recursively.d.ts +7 -0
- package/dist/cli/build/utils/read-paths-recursively.js +20 -0
- package/dist/cli/build/utils/ts-parse-file.d.ts +8 -0
- package/dist/cli/build/utils/ts-parse-file.js +12 -0
- package/dist/cli/config.d.ts +41 -0
- package/dist/cli/config.js +92 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +12 -0
- package/dist/cli/templates/shims/empty.d.ts +2 -0
- package/dist/cli/templates/shims/env.d.ts +1 -0
- package/dist/cli/templates/shims/env.js +1 -0
- package/dist/cli/templates/shims/node-fs.d.ts +17 -0
- package/dist/cli/templates/shims/node-fs.js +51 -0
- package/dist/cli/templates/shims/throw.d.ts +0 -0
- package/dist/cli/templates/shims/{throw.ts → throw.js} +1 -0
- package/dist/cli/templates/worker.d.ts +5 -0
- package/dist/cli/templates/worker.js +67 -0
- package/package.json +29 -12
- package/dist/api/chunk-VTBEIZPQ.mjs +0 -32
- package/dist/api/get-cloudflare-context.mjs +0 -6
- package/dist/api/index.d.mts +0 -1
- package/dist/api/index.mjs +0 -6
- package/dist/cli/constants/incremental-cache.ts +0 -8
- package/dist/cli/index.mjs +0 -7424
- package/dist/cli/templates/cache-handler/index.ts +0 -1
- package/dist/cli/templates/cache-handler/open-next-cache-handler.ts +0 -148
- package/dist/cli/templates/cache-handler/utils.ts +0 -41
- package/dist/cli/templates/shims/env.ts +0 -1
- package/dist/cli/templates/shims/node-fs.ts +0 -69
- package/dist/cli/templates/worker.ts +0 -156
- /package/dist/cli/templates/shims/{empty.ts → empty.js} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { appendFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import mockFs from "mock-fs";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { extractProjectEnvVars } from "./extract-project-env-vars";
|
|
5
|
+
const options = { monorepoRoot: "", appPath: "" };
|
|
6
|
+
describe("extractProjectEnvVars", () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
mockFs({
|
|
9
|
+
".env": "ENV_VAR=value",
|
|
10
|
+
".env.local": "ENV_LOCAL_VAR=value",
|
|
11
|
+
".env.development": "ENV_DEV_VAR=value",
|
|
12
|
+
".env.development.local": "ENV_DEV_LOCAL_VAR=value",
|
|
13
|
+
".env.production": "ENV_PROD_VAR=value",
|
|
14
|
+
".env.production.local": "ENV_PROD_LOCAL_VAR=value",
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => mockFs.restore());
|
|
18
|
+
it("should extract production env vars", () => {
|
|
19
|
+
const result = extractProjectEnvVars("production", options);
|
|
20
|
+
expect(result).toEqual({
|
|
21
|
+
ENV_LOCAL_VAR: "value",
|
|
22
|
+
ENV_PROD_LOCAL_VAR: "value",
|
|
23
|
+
ENV_PROD_VAR: "value",
|
|
24
|
+
ENV_VAR: "value",
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
it("should extract development env vars", () => {
|
|
28
|
+
writeFileSync(".dev.vars", 'NEXTJS_ENV = "development"');
|
|
29
|
+
const result = extractProjectEnvVars("development", options);
|
|
30
|
+
expect(result).toEqual({
|
|
31
|
+
ENV_LOCAL_VAR: "value",
|
|
32
|
+
ENV_DEV_LOCAL_VAR: "value",
|
|
33
|
+
ENV_DEV_VAR: "value",
|
|
34
|
+
ENV_VAR: "value",
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
it("should override env vars with those in a local file", () => {
|
|
38
|
+
writeFileSync(".env.production.local", "ENV_PROD_VAR=overridden");
|
|
39
|
+
const result = extractProjectEnvVars("production", options);
|
|
40
|
+
expect(result).toEqual({
|
|
41
|
+
ENV_LOCAL_VAR: "value",
|
|
42
|
+
ENV_PROD_VAR: "overridden",
|
|
43
|
+
ENV_VAR: "value",
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it("should support referencing variables", () => {
|
|
47
|
+
appendFileSync(".env.production.local", "\nENV_PROD_LOCAL_VAR_REF=$ENV_PROD_LOCAL_VAR");
|
|
48
|
+
const result = extractProjectEnvVars("production", options);
|
|
49
|
+
expect(result).toEqual({
|
|
50
|
+
ENV_LOCAL_VAR: "value",
|
|
51
|
+
ENV_PROD_LOCAL_VAR: "value",
|
|
52
|
+
ENV_PROD_LOCAL_VAR_REF: "value",
|
|
53
|
+
ENV_PROD_VAR: "value",
|
|
54
|
+
ENV_VAR: "value",
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function normalizePath(path: string): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively reads all file paths in a directory.
|
|
5
|
+
*
|
|
6
|
+
* @param dir Directory to recursively read from.
|
|
7
|
+
* @returns Array of all paths for all files in a directory.
|
|
8
|
+
*/
|
|
9
|
+
export function readPathsRecursively(dir) {
|
|
10
|
+
try {
|
|
11
|
+
const files = readdirSync(dir, { withFileTypes: true });
|
|
12
|
+
return files.flatMap((file) => {
|
|
13
|
+
const filePath = join(dir, file.name);
|
|
14
|
+
return file.isDirectory() ? readPathsRecursively(filePath) : filePath;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as ts from "ts-morph";
|
|
2
|
+
/**
|
|
3
|
+
* Parses a javascript file using ts-morph.
|
|
4
|
+
*
|
|
5
|
+
* @param fileContent the content of the file to parse
|
|
6
|
+
* @returns the parsed result
|
|
7
|
+
*/
|
|
8
|
+
export function tsParseFile(fileContent) {
|
|
9
|
+
const project = new ts.Project();
|
|
10
|
+
const sourceFile = project.createSourceFile("file.js", fileContent);
|
|
11
|
+
return sourceFile;
|
|
12
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type Config = {
|
|
2
|
+
build: {
|
|
3
|
+
skipNextBuild: boolean;
|
|
4
|
+
shouldMinify: boolean;
|
|
5
|
+
};
|
|
6
|
+
paths: {
|
|
7
|
+
source: {
|
|
8
|
+
root: string;
|
|
9
|
+
dotNext: string;
|
|
10
|
+
standaloneRoot: string;
|
|
11
|
+
};
|
|
12
|
+
output: {
|
|
13
|
+
root: string;
|
|
14
|
+
assets: string;
|
|
15
|
+
dotNext: string;
|
|
16
|
+
standaloneRoot: string;
|
|
17
|
+
standaloneApp: string;
|
|
18
|
+
standaloneAppDotNext: string;
|
|
19
|
+
standaloneAppServer: string;
|
|
20
|
+
};
|
|
21
|
+
internal: {
|
|
22
|
+
package: string;
|
|
23
|
+
templates: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
internalPackageName: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Computes the configuration.
|
|
30
|
+
*
|
|
31
|
+
* @param projectOpts The options for the project
|
|
32
|
+
* @returns The configuration, see `Config`
|
|
33
|
+
*/
|
|
34
|
+
export declare function getConfig(projectOpts: ProjectOptions): Config;
|
|
35
|
+
export declare function containsDotNextDir(folder: string): boolean;
|
|
36
|
+
export type ProjectOptions = {
|
|
37
|
+
sourceDir: string;
|
|
38
|
+
outputDir: string;
|
|
39
|
+
skipNextBuild: boolean;
|
|
40
|
+
minify: boolean;
|
|
41
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
const PACKAGE_NAME = "@opennextjs/cloudflare";
|
|
4
|
+
/**
|
|
5
|
+
* Computes the configuration.
|
|
6
|
+
*
|
|
7
|
+
* @param projectOpts The options for the project
|
|
8
|
+
* @returns The configuration, see `Config`
|
|
9
|
+
*/
|
|
10
|
+
export function getConfig(projectOpts) {
|
|
11
|
+
const sourceDirDotNext = join(projectOpts.sourceDir, ".next");
|
|
12
|
+
const dotNext = join(projectOpts.outputDir, ".next");
|
|
13
|
+
const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
|
|
14
|
+
const standaloneRoot = join(dotNext, "standalone");
|
|
15
|
+
const standaloneApp = join(standaloneRoot, appPath);
|
|
16
|
+
const standaloneAppDotNext = join(standaloneApp, ".next");
|
|
17
|
+
const standaloneAppServer = join(standaloneAppDotNext, "server");
|
|
18
|
+
const nodeModules = join(standaloneApp, "node_modules");
|
|
19
|
+
const internalPackage = join(nodeModules, ...PACKAGE_NAME.split("/"));
|
|
20
|
+
const internalTemplates = join(internalPackage, "cli", "templates");
|
|
21
|
+
return {
|
|
22
|
+
build: {
|
|
23
|
+
skipNextBuild: projectOpts.skipNextBuild,
|
|
24
|
+
shouldMinify: projectOpts.minify,
|
|
25
|
+
},
|
|
26
|
+
paths: {
|
|
27
|
+
source: {
|
|
28
|
+
root: projectOpts.sourceDir,
|
|
29
|
+
dotNext: sourceDirDotNext,
|
|
30
|
+
standaloneRoot: join(sourceDirDotNext, "standalone"),
|
|
31
|
+
},
|
|
32
|
+
output: {
|
|
33
|
+
root: projectOpts.outputDir,
|
|
34
|
+
assets: join(projectOpts.outputDir, "assets"),
|
|
35
|
+
dotNext,
|
|
36
|
+
standaloneRoot,
|
|
37
|
+
standaloneApp,
|
|
38
|
+
standaloneAppDotNext,
|
|
39
|
+
standaloneAppServer,
|
|
40
|
+
},
|
|
41
|
+
internal: {
|
|
42
|
+
package: internalPackage,
|
|
43
|
+
templates: internalTemplates,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
internalPackageName: PACKAGE_NAME,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function containsDotNextDir(folder) {
|
|
50
|
+
try {
|
|
51
|
+
return statSync(join(folder, ".next")).isDirectory();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* It basically tries to find the path that the application is under inside the `.next/standalone` directory, using the `.next/server` directory
|
|
59
|
+
* presence as the condition that needs to be met.
|
|
60
|
+
*
|
|
61
|
+
* For example:
|
|
62
|
+
* When I build the api application the `.next/server` directory is located in:
|
|
63
|
+
* `<dotNextDir>/standalone/next-apps/api/.next/server`
|
|
64
|
+
* and the function here given the `dotNextDir` returns `next-apps/api`
|
|
65
|
+
*/
|
|
66
|
+
function getNextjsApplicationPath(dotNextDir) {
|
|
67
|
+
const serverPath = findServerParentPath(dotNextDir);
|
|
68
|
+
if (!serverPath) {
|
|
69
|
+
throw new Error(`Unexpected Error: no \`.next/server\` folder could be found in \`${serverPath}\``);
|
|
70
|
+
}
|
|
71
|
+
return relative(join(dotNextDir, "standalone"), serverPath);
|
|
72
|
+
}
|
|
73
|
+
function findServerParentPath(parentPath) {
|
|
74
|
+
try {
|
|
75
|
+
if (statSync(join(parentPath, ".next", "server")).isDirectory()) {
|
|
76
|
+
return parentPath;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
/* empty */
|
|
81
|
+
}
|
|
82
|
+
const folders = readdirSync(parentPath);
|
|
83
|
+
for (const folder of folders) {
|
|
84
|
+
const subFolder = join(parentPath, folder);
|
|
85
|
+
if (statSync(join(parentPath, folder)).isDirectory()) {
|
|
86
|
+
const dirServerPath = findServerParentPath(subFolder);
|
|
87
|
+
if (dirServerPath) {
|
|
88
|
+
return dirServerPath;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { getArgs } from "./args.js";
|
|
4
|
+
import { build } from "./build/index.js";
|
|
5
|
+
const nextAppDir = process.cwd();
|
|
6
|
+
const { skipNextBuild, outputDir, minify } = getArgs();
|
|
7
|
+
await build({
|
|
8
|
+
sourceDir: nextAppDir,
|
|
9
|
+
outputDir: resolve(outputDir ?? nextAppDir, ".open-next"),
|
|
10
|
+
skipNextBuild,
|
|
11
|
+
minify,
|
|
12
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loadEnvConfig(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function loadEnvConfig() { }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const nodeFs: {
|
|
2
|
+
existsSync: typeof existsSync;
|
|
3
|
+
readFile: typeof readFile;
|
|
4
|
+
readFileSync: typeof readFileSync;
|
|
5
|
+
writeFile: typeof writeFile;
|
|
6
|
+
mkdir: typeof mkdir;
|
|
7
|
+
stat: typeof stat;
|
|
8
|
+
};
|
|
9
|
+
declare function existsSync(path: string): boolean;
|
|
10
|
+
declare function readFile(path: string, options: unknown): Promise<unknown>;
|
|
11
|
+
declare function readFileSync(path: string, options: unknown): unknown;
|
|
12
|
+
declare function writeFile(file: string, data: unknown): Promise<boolean>;
|
|
13
|
+
declare function mkdir(dir: string): Promise<void>;
|
|
14
|
+
declare function stat(file: string): Promise<{
|
|
15
|
+
mtime: Date;
|
|
16
|
+
}>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/node-fs-methods.ts
|
|
2
|
+
export const nodeFs = {
|
|
3
|
+
existsSync,
|
|
4
|
+
readFile,
|
|
5
|
+
readFileSync,
|
|
6
|
+
writeFile,
|
|
7
|
+
mkdir,
|
|
8
|
+
stat,
|
|
9
|
+
};
|
|
10
|
+
const FILES = new Map();
|
|
11
|
+
const MTIME = Date.now();
|
|
12
|
+
function existsSync(path) {
|
|
13
|
+
console.log("existsSync", path, new Error().stack?.split("\n").slice(1).join("\n"));
|
|
14
|
+
return FILES.has(path);
|
|
15
|
+
}
|
|
16
|
+
async function readFile(path, options) {
|
|
17
|
+
console.log("readFile", { path, options }
|
|
18
|
+
// new Error().stack.split("\n").slice(1).join("\n"),
|
|
19
|
+
);
|
|
20
|
+
if (!FILES.has(path)) {
|
|
21
|
+
throw new Error(path + "does not exist");
|
|
22
|
+
}
|
|
23
|
+
return FILES.get(path);
|
|
24
|
+
}
|
|
25
|
+
function readFileSync(path, options) {
|
|
26
|
+
console.log("readFileSync", { path, options }
|
|
27
|
+
// new Error().stack.split("\n").slice(1).join("\n"),
|
|
28
|
+
);
|
|
29
|
+
if (!FILES.has(path)) {
|
|
30
|
+
throw new Error(path + "does not exist");
|
|
31
|
+
}
|
|
32
|
+
return FILES.get(path);
|
|
33
|
+
}
|
|
34
|
+
async function writeFile(file, data) {
|
|
35
|
+
console.log("writeFile", { file, data }
|
|
36
|
+
// new Error().stack.split("\n").slice(1).join("\n"),
|
|
37
|
+
);
|
|
38
|
+
FILES.set(file, data);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
async function mkdir(dir) {
|
|
42
|
+
console.log("mkdir", dir
|
|
43
|
+
//new Error().stack.split("\n").slice(1).join("\n"),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
async function stat(file) {
|
|
47
|
+
console.log("stat", file
|
|
48
|
+
// new Error().stack.split("\n").slice(1).join("\n"),
|
|
49
|
+
);
|
|
50
|
+
return { mtime: new Date(MTIME) };
|
|
51
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
// @ts-expect-error: resolved by wrangler build
|
|
3
|
+
import { handler as middlewareHandler } from "./middleware/handler.mjs";
|
|
4
|
+
// @ts-expect-error: resolved by wrangler build
|
|
5
|
+
import { handler as serverHandler } from "./server-functions/default/handler.mjs";
|
|
6
|
+
const cloudflareContextALS = new AsyncLocalStorage();
|
|
7
|
+
// Note: this symbol needs to be kept in sync with the one defined in `src/api/get-cloudflare-context.ts`
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
globalThis[Symbol.for("__cloudflare-context__")] = new Proxy({}, {
|
|
10
|
+
ownKeys: () => Reflect.ownKeys(cloudflareContextALS.getStore()),
|
|
11
|
+
getOwnPropertyDescriptor: (_, ...args) => Reflect.getOwnPropertyDescriptor(cloudflareContextALS.getStore(), ...args),
|
|
12
|
+
get: (_, property) => Reflect.get(cloudflareContextALS.getStore(), property),
|
|
13
|
+
set: (_, property, value) => Reflect.set(cloudflareContextALS.getStore(), property, value),
|
|
14
|
+
});
|
|
15
|
+
export default {
|
|
16
|
+
async fetch(request, env, ctx) {
|
|
17
|
+
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, async () => {
|
|
18
|
+
const url = new URL(request.url);
|
|
19
|
+
if (process.env.__PROCESS_ENV_POPULATED !== "1") {
|
|
20
|
+
await populateProcessEnv(url, env.NEXTJS_ENV);
|
|
21
|
+
process.env.__PROCESS_ENV_POPULATED = "1";
|
|
22
|
+
}
|
|
23
|
+
if (url.pathname === "/_next/image") {
|
|
24
|
+
const imageUrl = url.searchParams.get("url") ?? "";
|
|
25
|
+
return imageUrl.startsWith("/")
|
|
26
|
+
? env.ASSETS.fetch(new URL(imageUrl, request.url))
|
|
27
|
+
: fetch(imageUrl, { cf: { cacheEverything: true } });
|
|
28
|
+
}
|
|
29
|
+
// The Middleware handler can return either a `Response` or a `Request`:
|
|
30
|
+
// - `Response`s should be returned early
|
|
31
|
+
// - `Request`s are handled by the Next server
|
|
32
|
+
const reqOrResp = await middlewareHandler(request, env, ctx);
|
|
33
|
+
if (reqOrResp instanceof Response) {
|
|
34
|
+
return reqOrResp;
|
|
35
|
+
}
|
|
36
|
+
return serverHandler(reqOrResp, env, ctx);
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Populate process.env with:
|
|
42
|
+
* - the variables from Next .env* files
|
|
43
|
+
* - the origin resolver information
|
|
44
|
+
*
|
|
45
|
+
* Note that cloudflare env string values are copied by the middleware handler.
|
|
46
|
+
*/
|
|
47
|
+
async function populateProcessEnv(url, nextJsEnv) {
|
|
48
|
+
if (process.env.__PROCESS_ENV_POPULATED === "1") {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// @ts-expect-error: resolved by wrangler build
|
|
52
|
+
const nextEnvVars = await import("./.env.mjs");
|
|
53
|
+
const mode = nextJsEnv ?? "production";
|
|
54
|
+
if (nextEnvVars[mode]) {
|
|
55
|
+
for (const key in nextEnvVars[mode]) {
|
|
56
|
+
process.env[key] = nextEnvVars[mode][key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Set the default Origin for the origin resolver.
|
|
60
|
+
process.env.OPEN_NEXT_ORIGIN = JSON.stringify({
|
|
61
|
+
default: {
|
|
62
|
+
host: url.hostname,
|
|
63
|
+
protocol: url.protocol.slice(0, -1),
|
|
64
|
+
port: url.port,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennextjs/cloudflare",
|
|
3
3
|
"description": "Cloudflare builder for next apps",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"opennextjs-cloudflare": "dist/cli/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/api/index.js",
|
|
10
|
+
"types": "./dist/api/index.d.ts",
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
|
-
"import": "./dist/api/index.
|
|
11
|
-
"types": "./dist/api/index.d.
|
|
13
|
+
"import": "./dist/api/index.js",
|
|
14
|
+
"types": "./dist/api/index.d.ts",
|
|
15
|
+
"default": "./dist/api/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./*": {
|
|
18
|
+
"import": "./dist/api/*.js",
|
|
19
|
+
"types": "./dist/api/*.d.ts",
|
|
20
|
+
"default": "./dist/api/*.js"
|
|
12
21
|
}
|
|
13
22
|
},
|
|
14
23
|
"files": [
|
|
@@ -21,6 +30,7 @@
|
|
|
21
30
|
"directory": "packages/cloudflare"
|
|
22
31
|
},
|
|
23
32
|
"keywords": [
|
|
33
|
+
"opennextjs-cloudflare",
|
|
24
34
|
"cloudflare",
|
|
25
35
|
"workers",
|
|
26
36
|
"next.js"
|
|
@@ -37,25 +47,32 @@
|
|
|
37
47
|
"@types/node": "^22.2.0",
|
|
38
48
|
"esbuild": "^0.23.0",
|
|
39
49
|
"eslint": "^9.11.1",
|
|
50
|
+
"eslint-plugin-import": "^2.31.0",
|
|
51
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
40
52
|
"eslint-plugin-unicorn": "^55.0.0",
|
|
41
53
|
"glob": "^11.0.0",
|
|
42
54
|
"globals": "^15.9.0",
|
|
43
55
|
"next": "14.2.11",
|
|
44
56
|
"package-manager-detector": "^0.2.0",
|
|
45
|
-
"tsup": "^8.2.4",
|
|
46
57
|
"typescript": "^5.5.4",
|
|
47
58
|
"typescript-eslint": "^8.7.0",
|
|
48
|
-
"vitest": "^2.1.1"
|
|
59
|
+
"vitest": "^2.1.1",
|
|
60
|
+
"mock-fs": "^5.4.1",
|
|
61
|
+
"@types/mock-fs": "^4.13.4"
|
|
49
62
|
},
|
|
50
63
|
"dependencies": {
|
|
51
|
-
"
|
|
64
|
+
"@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@684",
|
|
65
|
+
"ts-morph": "^23.0.0",
|
|
66
|
+
"@dotenvx/dotenvx": "1.31.0"
|
|
52
67
|
},
|
|
53
68
|
"peerDependencies": {
|
|
54
|
-
"
|
|
69
|
+
"rimraf": "^6.0.1",
|
|
70
|
+
"wrangler": "^3.99.0"
|
|
55
71
|
},
|
|
56
72
|
"scripts": {
|
|
57
|
-
"
|
|
58
|
-
"build
|
|
73
|
+
"clean": "rimraf dist",
|
|
74
|
+
"build": "pnpm clean && tsc",
|
|
75
|
+
"build:watch": "tsc -w",
|
|
59
76
|
"lint:check": "eslint",
|
|
60
77
|
"lint:fix": "eslint --fix",
|
|
61
78
|
"ts:check": "tsc --noEmit",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// src/api/get-cloudflare-context.ts
|
|
2
|
-
import "server-only";
|
|
3
|
-
var cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
|
|
4
|
-
async function getCloudflareContext() {
|
|
5
|
-
const global = globalThis;
|
|
6
|
-
const cloudflareContext = global[cloudflareContextSymbol];
|
|
7
|
-
if (!cloudflareContext) {
|
|
8
|
-
return getCloudflareContextInNextDev();
|
|
9
|
-
}
|
|
10
|
-
return cloudflareContext;
|
|
11
|
-
}
|
|
12
|
-
var cloudflareContextInNextDevSymbol = Symbol.for("__next-dev/cloudflare-context__");
|
|
13
|
-
async function getCloudflareContextInNextDev() {
|
|
14
|
-
const global = globalThis;
|
|
15
|
-
if (!global[cloudflareContextInNextDevSymbol]) {
|
|
16
|
-
const { getPlatformProxy } = await import(
|
|
17
|
-
/* webpackIgnore: true */
|
|
18
|
-
`${"__wrangler".replaceAll("_", "")}`
|
|
19
|
-
);
|
|
20
|
-
const { env, cf, ctx } = await getPlatformProxy();
|
|
21
|
-
global[cloudflareContextInNextDevSymbol] = {
|
|
22
|
-
env,
|
|
23
|
-
cf,
|
|
24
|
-
ctx
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
return global[cloudflareContextInNextDevSymbol];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
getCloudflareContext
|
|
32
|
-
};
|
package/dist/api/index.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { CloudflareContext, getCloudflareContext } from './get-cloudflare-context.mjs';
|
package/dist/api/index.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const RSC_PREFETCH_SUFFIX = ".prefetch.rsc";
|
|
2
|
-
export const RSC_SUFFIX = ".rsc";
|
|
3
|
-
export const NEXT_DATA_SUFFIX = ".json";
|
|
4
|
-
export const NEXT_META_SUFFIX = ".meta";
|
|
5
|
-
export const NEXT_BODY_SUFFIX = ".body";
|
|
6
|
-
export const NEXT_HTML_SUFFIX = ".html";
|
|
7
|
-
|
|
8
|
-
export const SEED_DATA_DIR = "cdn-cgi/_cf_seed_data";
|