@opennextjs/cloudflare 0.3.1 → 0.3.3

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.
@@ -4,3 +4,10 @@ import { Config } from "../config.js";
4
4
  * Bundle the Open Next server.
5
5
  */
6
6
  export declare function bundleServer(config: Config, openNextOptions: BuildOptions): Promise<void>;
7
+ /**
8
+ * Gets the path of the worker.js file generated by the build process
9
+ *
10
+ * @param openNextOptions the open-next build options
11
+ * @returns the path of the worker.js file that the build process generates
12
+ */
13
+ export declare function getOutputWorkerPath(openNextOptions: BuildOptions): string;
@@ -82,13 +82,12 @@ fetch = globalThis.fetch;
82
82
  const CustomRequest = class extends globalThis.Request {
83
83
  constructor(input, init) {
84
84
  if (init) {
85
- init = {
86
- ...init,
87
- cache: undefined,
88
- // https://github.com/cloudflare/workerd/issues/2746
89
- // https://github.com/cloudflare/workerd/issues/3245
90
- body: init.body instanceof __cf_stream.Readable ? ReadableStream.from(init.body) : init.body,
91
- };
85
+ delete init.cache;
86
+ // https://github.com/cloudflare/workerd/issues/2746
87
+ // https://github.com/cloudflare/workerd/issues/3245
88
+ Object.defineProperty(init, "body", {
89
+ value: init.body instanceof __cf_stream.Readable ? ReadableStream.from(init.body) : init.body;
90
+ });
92
91
  }
93
92
  super(input, init);
94
93
  }
@@ -107,7 +106,7 @@ globalThis.__BUILD_TIMESTAMP_MS__ = ${Date.now()};
107
106
  const packagePosixPath = packagePath.split(path.sep).join(path.posix.sep);
108
107
  fs.writeFileSync(path.join(outputPath, "handler.mjs"), `export * from "./${packagePosixPath}/handler.mjs";`);
109
108
  }
110
- console.log(`\x1b[35mWorker saved in \`${openNextServerBundle}\` 🚀\n\x1b[0m`);
109
+ console.log(`\x1b[35mWorker saved in \`${getOutputWorkerPath(openNextOptions)}\` 🚀\n\x1b[0m`);
111
110
  }
112
111
  /**
113
112
  * This function applies string replacements on the bundled worker code necessary to get it to run in workerd
@@ -186,3 +185,12 @@ async function patchCodeWithValidations(code, patches) {
186
185
  console.log(`All ${patches.length} patches applied\n`);
187
186
  return patchedCode;
188
187
  }
188
+ /**
189
+ * Gets the path of the worker.js file generated by the build process
190
+ *
191
+ * @param openNextOptions the open-next build options
192
+ * @returns the path of the worker.js file that the build process generates
193
+ */
194
+ export function getOutputWorkerPath(openNextOptions) {
195
+ return path.join(openNextOptions.outputDir, "worker.js");
196
+ }
@@ -1,4 +1,4 @@
1
- import { cpSync } from "node:fs";
1
+ import { cpSync, existsSync } from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
4
  import { buildNextjsApp, setStandaloneBuildMode } from "@opennextjs/aws/build/buildNextApp.js";
@@ -9,7 +9,9 @@ import { createMiddleware } from "@opennextjs/aws/build/createMiddleware.js";
9
9
  import * as buildHelper from "@opennextjs/aws/build/helper.js";
10
10
  import { printHeader, showWarningOnWindows } from "@opennextjs/aws/build/utils.js";
11
11
  import logger from "@opennextjs/aws/logger.js";
12
+ import { getPackageTemplatesDirPath } from "../../utils/get-package-templates-dir-path.js";
12
13
  import { containsDotNextDir, getConfig } from "../config.js";
14
+ import { askConfirmation } from "../utils/ask-confirmation.js";
13
15
  import { bundleServer } from "./bundle-server.js";
14
16
  import { compileEnvFiles } from "./open-next/compile-env-files.js";
15
17
  import { copyCacheAssets } from "./open-next/copyCacheAssets.js";
@@ -27,6 +29,7 @@ export async function build(projectOpts) {
27
29
  const baseDir = projectOpts.sourceDir;
28
30
  const require = createRequire(import.meta.url);
29
31
  const openNextDistDir = dirname(require.resolve("@opennextjs/aws/index.js"));
32
+ await createOpenNextConfigIfNotExistent(projectOpts);
30
33
  const { config, buildDir } = await compileOpenNextConfig(baseDir);
31
34
  ensureCloudflareConfig(config);
32
35
  // Initialize options
@@ -75,6 +78,23 @@ export async function build(projectOpts) {
75
78
  await bundleServer(projConfig, options);
76
79
  logger.info("OpenNext build complete.");
77
80
  }
81
+ /**
82
+ * Creates a `open-next.config.ts` file for the user if it doesn't exist, but only after asking for the user's confirmation.
83
+ *
84
+ * If the user refuses an error is thrown (since the file is mandatory).
85
+ *
86
+ * @param projectOpts The options for the project
87
+ */
88
+ async function createOpenNextConfigIfNotExistent(projectOpts) {
89
+ const openNextConfigPath = join(projectOpts.sourceDir, "open-next.config.ts");
90
+ if (!existsSync(openNextConfigPath)) {
91
+ const answer = await askConfirmation("Missing required `open-next.config.ts` file, do you want to create one?");
92
+ if (!answer) {
93
+ throw new Error("The `open-next.config.ts` file is required, aborting!");
94
+ }
95
+ cpSync(join(getPackageTemplatesDirPath(), "defaults", "open-next.config.ts"), openNextConfigPath);
96
+ }
97
+ }
78
98
  /**
79
99
  * Ensures open next is configured for cloudflare.
80
100
  *
@@ -94,30 +114,30 @@ function ensureCloudflareConfig(config) {
94
114
  mwUseFetchProxy: config.middleware?.override?.proxyExternalRequest === "fetch",
95
115
  };
96
116
  if (Object.values(requirements).some((satisfied) => !satisfied)) {
97
- throw new Error(`open-next.config.ts should contain:
98
- {
99
- default: {
100
- override: {
101
- wrapper: "cloudflare-node",
102
- converter: "edge",
103
- incrementalCache: "dummy" | function,
104
- tagCache: "dummy",
105
- queue: "dummy",
106
- },
107
- },
117
+ throw new Error("The `open-next.config.ts` should have a default export like this:\n\n" +
118
+ `{
119
+ default: {
120
+ override: {
121
+ wrapper: "cloudflare-node",
122
+ converter: "edge",
123
+ incrementalCache: "dummy" | function,
124
+ tagCache: "dummy",
125
+ queue: "dummy",
126
+ },
127
+ },
108
128
 
109
- middleware: {
110
- external: true,
111
- override: {
112
- wrapper: "cloudflare-edge",
113
- converter: "edge",
114
- proxyExternalRequest: "fetch",
115
- },
116
- },
129
+ middleware: {
130
+ external: true,
131
+ override: {
132
+ wrapper: "cloudflare-edge",
133
+ converter: "edge",
134
+ proxyExternalRequest: "fetch",
135
+ },
136
+ },
117
137
 
118
- "dangerous": {
119
- "enableCacheInterception": false
120
- }
121
- }`);
138
+ "dangerous": {
139
+ "enableCacheInterception": false
140
+ },
141
+ }\n\n`.replace(/^ {8}/gm, ""));
122
142
  }
123
143
  }
@@ -3,4 +3,4 @@ import { Config } from "../../../config.js";
3
3
  /**
4
4
  * Copies the template files present in the cloudflare adapter package into the standalone node_modules folder
5
5
  */
6
- export declare function copyPackageCliFiles(packageDistDir: string, config: Config, openNextConfig: BuildOptions): void;
6
+ export declare function copyPackageCliFiles(packageDistDir: string, config: Config, openNextOptions: BuildOptions): void;
@@ -1,12 +1,13 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { getOutputWorkerPath } from "../../bundle-server.js";
3
4
  /**
4
5
  * Copies the template files present in the cloudflare adapter package into the standalone node_modules folder
5
6
  */
6
- export function copyPackageCliFiles(packageDistDir, config, openNextConfig) {
7
+ export function copyPackageCliFiles(packageDistDir, config, openNextOptions) {
7
8
  console.log("# copyPackageTemplateFiles");
8
9
  const sourceDir = path.join(packageDistDir, "cli");
9
10
  const destinationDir = path.join(config.paths.internal.package, "cli");
10
11
  fs.cpSync(sourceDir, destinationDir, { recursive: true });
11
- fs.copyFileSync(path.join(packageDistDir, "cli", "templates", "worker.js"), path.join(openNextConfig.outputDir, "worker.js"));
12
+ fs.copyFileSync(path.join(packageDistDir, "cli", "templates", "worker.js"), getOutputWorkerPath(openNextOptions));
12
13
  }
@@ -0,0 +1 @@
1
+ export declare function askConfirmation(message: string): Promise<boolean>;
@@ -0,0 +1,13 @@
1
+ import Enquirer from "enquirer";
2
+ export async function askConfirmation(message) {
3
+ const questionName = crypto.randomUUID();
4
+ const enquirerAnswersObject = await Enquirer.prompt({
5
+ name: questionName,
6
+ message,
7
+ type: "confirm",
8
+ initial: "y",
9
+ });
10
+ console.log("");
11
+ const answer = !!enquirerAnswersObject[questionName];
12
+ return answer;
13
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utility for getting the resolved path to the package's templates directory
3
+ *
4
+ * @returns the resolved path of the templates directory
5
+ */
6
+ export declare function getPackageTemplatesDirPath(): string;
@@ -0,0 +1,10 @@
1
+ import * as path from "node:path";
2
+ const templatesDirPath = path.resolve(`${import.meta.dirname}/../../templates`);
3
+ /**
4
+ * Utility for getting the resolved path to the package's templates directory
5
+ *
6
+ * @returns the resolved path of the templates directory
7
+ */
8
+ export function getPackageTemplatesDirPath() {
9
+ return templatesDirPath;
10
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@opennextjs/cloudflare",
3
3
  "description": "Cloudflare builder for next apps",
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -22,7 +22,8 @@
22
22
  },
23
23
  "files": [
24
24
  "README.md",
25
- "dist"
25
+ "dist",
26
+ "templates"
26
27
  ],
27
28
  "repository": {
28
29
  "type": "git",
@@ -63,7 +64,8 @@
63
64
  "@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@684",
64
65
  "glob": "^11.0.0",
65
66
  "rimraf": "^6.0.1",
66
- "ts-morph": "^23.0.0"
67
+ "ts-morph": "^23.0.0",
68
+ "enquirer": "^2.4.1"
67
69
  },
68
70
  "peerDependencies": {
69
71
  "wrangler": "^3.99.0"
@@ -0,0 +1,30 @@
1
+ // default open-next.config.ts file created by @opennextjs/cloudflare
2
+
3
+ import cache from "@opennextjs/cloudflare/kvCache";
4
+
5
+ const config = {
6
+ default: {
7
+ override: {
8
+ wrapper: "cloudflare-node",
9
+ converter: "edge",
10
+ incrementalCache: async () => cache,
11
+ tagCache: "dummy",
12
+ queue: "dummy",
13
+ },
14
+ },
15
+
16
+ middleware: {
17
+ external: true,
18
+ override: {
19
+ wrapper: "cloudflare-edge",
20
+ converter: "edge",
21
+ proxyExternalRequest: "fetch",
22
+ },
23
+ },
24
+
25
+ dangerous: {
26
+ enableCacheInterception: false,
27
+ },
28
+ };
29
+
30
+ export default config;