this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: shuffle code around (#258)

authored by

Victor Berchet and committed by
GitHub
e6078b50 d39bff20

+324 -313
+119
packages/cloudflare/src/cli/build/build.ts
··· 1 + import { cpSync } from "node:fs"; 2 + import { createRequire } from "node:module"; 3 + import { dirname, join } from "node:path"; 4 + 5 + import { buildNextjsApp, setStandaloneBuildMode } from "@opennextjs/aws/build/buildNextApp.js"; 6 + import { compileCache } from "@opennextjs/aws/build/compileCache.js"; 7 + import { compileOpenNextConfig } from "@opennextjs/aws/build/compileConfig.js"; 8 + import { createCacheAssets, createStaticAssets } from "@opennextjs/aws/build/createAssets.js"; 9 + import { createMiddleware } from "@opennextjs/aws/build/createMiddleware.js"; 10 + import * as buildHelper from "@opennextjs/aws/build/helper.js"; 11 + import { printHeader, showWarningOnWindows } from "@opennextjs/aws/build/utils.js"; 12 + import logger from "@opennextjs/aws/logger.js"; 13 + 14 + import type { ProjectOptions } from "../config.js"; 15 + import { containsDotNextDir, getConfig } from "../config.js"; 16 + import { bundleServer } from "./bundle-server.js"; 17 + import { compileEnvFiles } from "./open-next/compile-env-files.js"; 18 + import { copyCacheAssets } from "./open-next/copyCacheAssets.js"; 19 + import { createServerBundle } from "./open-next/createServerBundle.js"; 20 + import { 21 + createOpenNextConfigIfNotExistent, 22 + createWranglerConfigIfNotExistent, 23 + ensureCloudflareConfig, 24 + } from "./utils/index.js"; 25 + 26 + /** 27 + * Builds the application in a format that can be passed to workerd 28 + * 29 + * It saves the output in a `.worker-next` directory 30 + * 31 + * @param projectOpts The options for the project 32 + */ 33 + export async function build(projectOpts: ProjectOptions): Promise<void> { 34 + printHeader("Cloudflare build"); 35 + 36 + showWarningOnWindows(); 37 + 38 + const baseDir = projectOpts.sourceDir; 39 + const require = createRequire(import.meta.url); 40 + const openNextDistDir = dirname(require.resolve("@opennextjs/aws/index.js")); 41 + 42 + await createOpenNextConfigIfNotExistent(projectOpts); 43 + 44 + const { config, buildDir } = await compileOpenNextConfig(baseDir); 45 + 46 + ensureCloudflareConfig(config); 47 + 48 + // Initialize options 49 + const options = buildHelper.normalizeOptions(config, openNextDistDir, buildDir); 50 + logger.setLevel(options.debug ? "debug" : "info"); 51 + 52 + // Do not minify the code so that we can apply string replacement patch. 53 + // Note that wrangler will still minify the bundle. 54 + options.minify = false; 55 + 56 + // Pre-build validation 57 + buildHelper.checkRunningInsideNextjsApp(options); 58 + logger.info(`App directory: ${options.appPath}`); 59 + buildHelper.printNextjsVersion(options); 60 + ensureNextjsVersionSupported(options); 61 + buildHelper.printOpenNextVersion(options); 62 + 63 + if (projectOpts.skipNextBuild) { 64 + logger.warn("Skipping Next.js build"); 65 + } else { 66 + // Build the next app 67 + printHeader("Building Next.js app"); 68 + setStandaloneBuildMode(options); 69 + buildNextjsApp(options); 70 + } 71 + 72 + if (!containsDotNextDir(projectOpts.sourceDir)) { 73 + throw new Error(`.next folder not found in ${projectOpts.sourceDir}`); 74 + } 75 + 76 + // Generate deployable bundle 77 + printHeader("Generating bundle"); 78 + buildHelper.initOutputDir(options); 79 + 80 + // Compile cache.ts 81 + compileCache(options); 82 + 83 + // Compile .env files 84 + compileEnvFiles(options); 85 + 86 + // Compile middleware 87 + await createMiddleware(options, { forceOnlyBuildOnce: true }); 88 + 89 + createStaticAssets(options); 90 + 91 + if (config.dangerous?.disableIncrementalCache !== true) { 92 + createCacheAssets(options); 93 + copyCacheAssets(options); 94 + } 95 + 96 + await createServerBundle(options); 97 + 98 + // TODO: drop this copy. 99 + // Copy the .next directory to the output directory so it can be mutated. 100 + cpSync(join(projectOpts.sourceDir, ".next"), join(projectOpts.outputDir, ".next"), { recursive: true }); 101 + 102 + const projConfig = getConfig(projectOpts); 103 + 104 + // TODO: rely on options only. 105 + await bundleServer(projConfig, options); 106 + 107 + if (!projectOpts.skipWranglerConfigCheck) { 108 + await createWranglerConfigIfNotExistent(projectOpts); 109 + } 110 + 111 + logger.info("OpenNext build complete."); 112 + } 113 + 114 + function ensureNextjsVersionSupported(options: buildHelper.BuildOptions) { 115 + if (buildHelper.compareSemver(options.nextVersion, "14.0.0") < 0) { 116 + logger.error("Next.js version unsupported, please upgrade to version 14 or greater."); 117 + process.exit(1); 118 + } 119 + }
+1 -32
packages/cloudflare/src/cli/build/bundle-server.ts
··· 8 8 9 9 import { Config } from "../config.js"; 10 10 import * as patches from "./patches/index.js"; 11 - import { normalizePath } from "./utils/index.js"; 11 + import { normalizePath, patchCodeWithValidations } from "./utils/index.js"; 12 12 13 13 /** The dist directory of the Cloudflare adapter package */ 14 14 const packageDistDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "../.."); ··· 188 188 })); 189 189 }, 190 190 }; 191 - } 192 - 193 - /** 194 - * Applies multiple code patches in order to a given piece of code, at each step it validates that the code 195 - * has actually been patched/changed, if not an error is thrown 196 - * 197 - * @param code the code to apply the patches to 198 - * @param patches array of tuples, containing a string indicating the target of the patching (for logging) and 199 - * a patching function that takes a string (pre-patch code) and returns a string (post-patch code) 200 - * @returns the patched code 201 - */ 202 - async function patchCodeWithValidations( 203 - code: string, 204 - patches: [string, (code: string) => string | Promise<string>, opts?: { isOptional?: boolean }][] 205 - ): Promise<string> { 206 - console.log(`Applying code patches:`); 207 - let patchedCode = code; 208 - 209 - for (const [target, patchFunction, opts] of patches) { 210 - console.log(` - patching ${target}`); 211 - 212 - const prePatchCode = patchedCode; 213 - patchedCode = await patchFunction(patchedCode); 214 - 215 - if (!opts?.isOptional && prePatchCode === patchedCode) { 216 - throw new Error(`Failed to patch ${target}`); 217 - } 218 - } 219 - 220 - console.log(`All ${patches.length} patches applied\n`); 221 - return patchedCode; 222 191 } 223 192 224 193 /**
-279
packages/cloudflare/src/cli/build/index.ts
··· 1 - import { cpSync, existsSync, readFileSync, writeFileSync } from "node:fs"; 2 - import { createRequire } from "node:module"; 3 - import { dirname, join } from "node:path"; 4 - 5 - import { buildNextjsApp, setStandaloneBuildMode } from "@opennextjs/aws/build/buildNextApp.js"; 6 - import { compileCache } from "@opennextjs/aws/build/compileCache.js"; 7 - import { compileOpenNextConfig } from "@opennextjs/aws/build/compileConfig.js"; 8 - import { createCacheAssets, createStaticAssets } from "@opennextjs/aws/build/createAssets.js"; 9 - import { createMiddleware } from "@opennextjs/aws/build/createMiddleware.js"; 10 - import * as buildHelper from "@opennextjs/aws/build/helper.js"; 11 - import { printHeader, showWarningOnWindows } from "@opennextjs/aws/build/utils.js"; 12 - import logger from "@opennextjs/aws/logger.js"; 13 - import type { OpenNextConfig } from "@opennextjs/aws/types/open-next.js"; 14 - 15 - import { getPackageTemplatesDirPath } from "../../utils/get-package-templates-dir-path.js"; 16 - import type { ProjectOptions } from "../config.js"; 17 - import { containsDotNextDir, getConfig } from "../config.js"; 18 - import { askConfirmation } from "../utils/ask-confirmation.js"; 19 - import { bundleServer } from "./bundle-server.js"; 20 - import { compileEnvFiles } from "./open-next/compile-env-files.js"; 21 - import { copyCacheAssets } from "./open-next/copyCacheAssets.js"; 22 - import { createServerBundle } from "./open-next/createServerBundle.js"; 23 - 24 - /** 25 - * Builds the application in a format that can be passed to workerd 26 - * 27 - * It saves the output in a `.worker-next` directory 28 - * 29 - * @param projectOpts The options for the project 30 - */ 31 - export async function build(projectOpts: ProjectOptions): Promise<void> { 32 - printHeader("Cloudflare build"); 33 - 34 - showWarningOnWindows(); 35 - 36 - const baseDir = projectOpts.sourceDir; 37 - const require = createRequire(import.meta.url); 38 - const openNextDistDir = dirname(require.resolve("@opennextjs/aws/index.js")); 39 - 40 - await createOpenNextConfigIfNotExistent(projectOpts); 41 - 42 - const { config, buildDir } = await compileOpenNextConfig(baseDir); 43 - 44 - ensureCloudflareConfig(config); 45 - 46 - // Initialize options 47 - const options = buildHelper.normalizeOptions(config, openNextDistDir, buildDir); 48 - logger.setLevel(options.debug ? "debug" : "info"); 49 - 50 - // Do not minify the code so that we can apply string replacement patch. 51 - // Note that wrangler will still minify the bundle. 52 - options.minify = false; 53 - 54 - // Pre-build validation 55 - buildHelper.checkRunningInsideNextjsApp(options); 56 - logger.info(`App directory: ${options.appPath}`); 57 - buildHelper.printNextjsVersion(options); 58 - ensureNextjsVersionSupported(options); 59 - buildHelper.printOpenNextVersion(options); 60 - 61 - if (projectOpts.skipNextBuild) { 62 - logger.warn("Skipping Next.js build"); 63 - } else { 64 - // Build the next app 65 - printHeader("Building Next.js app"); 66 - setStandaloneBuildMode(options); 67 - buildNextjsApp(options); 68 - } 69 - 70 - if (!containsDotNextDir(projectOpts.sourceDir)) { 71 - throw new Error(`.next folder not found in ${projectOpts.sourceDir}`); 72 - } 73 - 74 - // Generate deployable bundle 75 - printHeader("Generating bundle"); 76 - buildHelper.initOutputDir(options); 77 - 78 - // Compile cache.ts 79 - compileCache(options); 80 - 81 - // Compile .env files 82 - compileEnvFiles(options); 83 - 84 - // Compile middleware 85 - await createMiddleware(options, { forceOnlyBuildOnce: true }); 86 - 87 - createStaticAssets(options); 88 - 89 - if (config.dangerous?.disableIncrementalCache !== true) { 90 - createCacheAssets(options); 91 - copyCacheAssets(options); 92 - } 93 - 94 - await createServerBundle(options); 95 - 96 - // TODO: drop this copy. 97 - // Copy the .next directory to the output directory so it can be mutated. 98 - cpSync(join(projectOpts.sourceDir, ".next"), join(projectOpts.outputDir, ".next"), { recursive: true }); 99 - 100 - const projConfig = getConfig(projectOpts); 101 - 102 - // TODO: rely on options only. 103 - await bundleServer(projConfig, options); 104 - 105 - if (!projectOpts.skipWranglerConfigCheck) { 106 - await createWranglerConfigIfNotExistent(projectOpts); 107 - } 108 - 109 - logger.info("OpenNext build complete."); 110 - } 111 - 112 - /** 113 - * Creates a `open-next.config.ts` file for the user if it doesn't exist, but only after asking for the user's confirmation. 114 - * 115 - * If the user refuses an error is thrown (since the file is mandatory). 116 - * 117 - * @param projectOpts The options for the project 118 - */ 119 - async function createOpenNextConfigIfNotExistent(projectOpts: ProjectOptions): Promise<void> { 120 - const openNextConfigPath = join(projectOpts.sourceDir, "open-next.config.ts"); 121 - 122 - if (!existsSync(openNextConfigPath)) { 123 - const answer = await askConfirmation( 124 - "Missing required `open-next.config.ts` file, do you want to create one?" 125 - ); 126 - 127 - if (!answer) { 128 - throw new Error("The `open-next.config.ts` file is required, aborting!"); 129 - } 130 - 131 - cpSync(join(getPackageTemplatesDirPath(), "defaults", "open-next.config.ts"), openNextConfigPath); 132 - } 133 - } 134 - 135 - /** 136 - * Ensures open next is configured for cloudflare. 137 - * 138 - * @param config OpenNext configuration. 139 - */ 140 - function ensureCloudflareConfig(config: OpenNextConfig) { 141 - const requirements = { 142 - dftUseCloudflareWrapper: config.default?.override?.wrapper === "cloudflare-node", 143 - dftUseEdgeConverter: config.default?.override?.converter === "edge", 144 - dftMaybeUseCache: 145 - config.default?.override?.incrementalCache === "dummy" || 146 - typeof config.default?.override?.incrementalCache === "function", 147 - dftUseDummyTagCacheAndQueue: 148 - config.default?.override?.tagCache === "dummy" && config.default?.override?.queue === "dummy", 149 - disableCacheInterception: config.dangerous?.enableCacheInterception !== true, 150 - mwIsMiddlewareExternal: config.middleware?.external == true, 151 - mwUseCloudflareWrapper: config.middleware?.override?.wrapper === "cloudflare-edge", 152 - mwUseEdgeConverter: config.middleware?.override?.converter === "edge", 153 - mwUseFetchProxy: config.middleware?.override?.proxyExternalRequest === "fetch", 154 - }; 155 - 156 - if (Object.values(requirements).some((satisfied) => !satisfied)) { 157 - throw new Error( 158 - "The `open-next.config.ts` should have a default export like this:\n\n" + 159 - `{ 160 - default: { 161 - override: { 162 - wrapper: "cloudflare-node", 163 - converter: "edge", 164 - incrementalCache: "dummy" | function, 165 - tagCache: "dummy", 166 - queue: "dummy", 167 - }, 168 - }, 169 - 170 - middleware: { 171 - external: true, 172 - override: { 173 - wrapper: "cloudflare-edge", 174 - converter: "edge", 175 - proxyExternalRequest: "fetch", 176 - }, 177 - }, 178 - 179 - "dangerous": { 180 - "enableCacheInterception": false 181 - }, 182 - }\n\n`.replace(/^ {8}/gm, "") 183 - ); 184 - } 185 - } 186 - 187 - /** 188 - * Creates a `wrangler.json` file for the user if a wrangler config file doesn't already exist, 189 - * but only after asking for the user's confirmation. 190 - * 191 - * If the user refuses a warning is shown (which offers ways to opt out of this check to the user). 192 - * 193 - * Note: we generate a wrangler.json file with comments instead of using the jsonc extension, 194 - * we decided to do that since json is more common than jsonc, wrangler also parses 195 - * them in the same way and we also expect developers to associate `wrangler.json` 196 - * files to the jsonc language 197 - * 198 - * @param projectOpts The options for the project 199 - */ 200 - async function createWranglerConfigIfNotExistent(projectOpts: ProjectOptions): Promise<void> { 201 - const possibleExts = ["toml", "json", "jsonc"]; 202 - 203 - const wranglerConfigFileExists = possibleExts.some((ext) => 204 - existsSync(join(projectOpts.sourceDir, `wrangler.${ext}`)) 205 - ); 206 - if (wranglerConfigFileExists) { 207 - return; 208 - } 209 - 210 - const answer = await askConfirmation( 211 - "No `wrangler.(toml|json|jsonc)` config file found, do you want to create one?" 212 - ); 213 - 214 - if (!answer) { 215 - console.warn( 216 - "No Wrangler config file created" + 217 - "\n" + 218 - "(to avoid this check use the `--skipWranglerConfigCheck` flag or set a `SKIP_WRANGLER_CONFIG_CHECK` environment variable to `yes`)" 219 - ); 220 - return; 221 - } 222 - 223 - let wranglerConfig = readFileSync(join(getPackageTemplatesDirPath(), "defaults", "wrangler.json"), "utf8"); 224 - 225 - const appName = getAppNameFromPackageJson(projectOpts.sourceDir) ?? "app-name"; 226 - if (appName) { 227 - wranglerConfig = wranglerConfig.replace('"app-name"', JSON.stringify(appName.replaceAll("_", "-"))); 228 - } 229 - 230 - const compatDate = await getLatestCompatDate(); 231 - if (compatDate) { 232 - wranglerConfig = wranglerConfig.replace( 233 - /"compatibility_date": "\d{4}-\d{2}-\d{2}"/, 234 - `"compatibility_date": ${JSON.stringify(compatDate)}` 235 - ); 236 - } 237 - 238 - writeFileSync(join(projectOpts.sourceDir, "wrangler.json"), wranglerConfig); 239 - } 240 - 241 - function getAppNameFromPackageJson(sourceDir: string): string | undefined { 242 - try { 243 - const packageJsonStr = readFileSync(join(sourceDir, "package.json"), "utf8"); 244 - const packageJson: Record<string, string> = JSON.parse(packageJsonStr); 245 - if (typeof packageJson.name === "string") return packageJson.name; 246 - } catch { 247 - /* empty */ 248 - } 249 - } 250 - 251 - export async function getLatestCompatDate(): Promise<string | undefined> { 252 - try { 253 - const resp = await fetch(`https://registry.npmjs.org/workerd`); 254 - const latestWorkerdVersion = ( 255 - (await resp.json()) as { 256 - "dist-tags": { latest: string }; 257 - } 258 - )["dist-tags"].latest; 259 - 260 - // The format of the workerd version is `major.yyyymmdd.patch`. 261 - const match = latestWorkerdVersion.match(/\d+\.(\d{4})(\d{2})(\d{2})\.\d+/); 262 - 263 - if (match) { 264 - const [, year, month, date] = match; 265 - const compatDate = `${year}-${month}-${date}`; 266 - 267 - return compatDate; 268 - } 269 - } catch { 270 - /* empty */ 271 - } 272 - } 273 - 274 - function ensureNextjsVersionSupported(options: buildHelper.BuildOptions) { 275 - if (buildHelper.compareSemver(options.nextVersion, "14.0.0") < 0) { 276 - logger.error("Next.js version unsupported, please upgrade to version 14 or greater."); 277 - process.exit(1); 278 - } 279 - }
+30
packages/cloudflare/src/cli/build/utils/apply-patches.ts
··· 1 + /** 2 + * Applies multiple code patches in order to a given piece of code, at each step it validates that the code 3 + * has actually been patched/changed, if not an error is thrown 4 + * 5 + * @param code the code to apply the patches to 6 + * @param patches array of tuples, containing a string indicating the target of the patching (for logging) and 7 + * a patching function that takes a string (pre-patch code) and returns a string (post-patch code) 8 + * @returns the patched code 9 + */ 10 + export async function patchCodeWithValidations( 11 + code: string, 12 + patches: [string, (code: string) => string | Promise<string>, opts?: { isOptional?: boolean }][] 13 + ): Promise<string> { 14 + console.log(`Applying code patches:`); 15 + let patchedCode = code; 16 + 17 + for (const [target, patchFunction, opts] of patches) { 18 + console.log(` - patching ${target}`); 19 + 20 + const prePatchCode = patchedCode; 21 + patchedCode = await patchFunction(patchedCode); 22 + 23 + if (!opts?.isOptional && prePatchCode === patchedCode) { 24 + throw new Error(`Failed to patch ${target}`); 25 + } 26 + } 27 + 28 + console.log(`All ${patches.length} patches applied\n`); 29 + return patchedCode; 30 + }
+116
packages/cloudflare/src/cli/build/utils/create-config-files.ts
··· 1 + import { cpSync, existsSync, readFileSync, writeFileSync } from "node:fs"; 2 + import { join } from "node:path"; 3 + 4 + import { getPackageTemplatesDirPath } from "../../../utils/get-package-templates-dir-path.js"; 5 + import type { ProjectOptions } from "../../config.js"; 6 + import { askConfirmation } from "../../utils/ask-confirmation.js"; 7 + 8 + /** 9 + * Creates a `wrangler.json` file for the user if a wrangler config file doesn't already exist, 10 + * but only after asking for the user's confirmation. 11 + * 12 + * If the user refuses a warning is shown (which offers ways to opt out of this check to the user). 13 + * 14 + * Note: we generate a wrangler.json file with comments instead of using the jsonc extension, 15 + * we decided to do that since json is more common than jsonc, wrangler also parses 16 + * them in the same way and we also expect developers to associate `wrangler.json` 17 + * files to the jsonc language 18 + * 19 + * @param projectOpts The options for the project 20 + */ 21 + export async function createWranglerConfigIfNotExistent(projectOpts: ProjectOptions): Promise<void> { 22 + const possibleExts = ["toml", "json", "jsonc"]; 23 + 24 + const wranglerConfigFileExists = possibleExts.some((ext) => 25 + existsSync(join(projectOpts.sourceDir, `wrangler.${ext}`)) 26 + ); 27 + if (wranglerConfigFileExists) { 28 + return; 29 + } 30 + 31 + const answer = await askConfirmation( 32 + "No `wrangler.(toml|json|jsonc)` config file found, do you want to create one?" 33 + ); 34 + 35 + if (!answer) { 36 + console.warn( 37 + "No Wrangler config file created" + 38 + "\n" + 39 + "(to avoid this check use the `--skipWranglerConfigCheck` flag or set a `SKIP_WRANGLER_CONFIG_CHECK` environment variable to `yes`)" 40 + ); 41 + return; 42 + } 43 + 44 + let wranglerConfig = readFileSync(join(getPackageTemplatesDirPath(), "defaults", "wrangler.json"), "utf8"); 45 + 46 + const appName = getAppNameFromPackageJson(projectOpts.sourceDir) ?? "app-name"; 47 + if (appName) { 48 + wranglerConfig = wranglerConfig.replace('"app-name"', JSON.stringify(appName.replaceAll("_", "-"))); 49 + } 50 + 51 + const compatDate = await getLatestCompatDate(); 52 + if (compatDate) { 53 + wranglerConfig = wranglerConfig.replace( 54 + /"compatibility_date": "\d{4}-\d{2}-\d{2}"/, 55 + `"compatibility_date": ${JSON.stringify(compatDate)}` 56 + ); 57 + } 58 + 59 + writeFileSync(join(projectOpts.sourceDir, "wrangler.json"), wranglerConfig); 60 + } 61 + 62 + function getAppNameFromPackageJson(sourceDir: string): string | undefined { 63 + try { 64 + const packageJsonStr = readFileSync(join(sourceDir, "package.json"), "utf8"); 65 + const packageJson: Record<string, string> = JSON.parse(packageJsonStr); 66 + if (typeof packageJson.name === "string") return packageJson.name; 67 + } catch { 68 + /* empty */ 69 + } 70 + } 71 + 72 + export async function getLatestCompatDate(): Promise<string | undefined> { 73 + try { 74 + const resp = await fetch(`https://registry.npmjs.org/workerd`); 75 + const latestWorkerdVersion = ( 76 + (await resp.json()) as { 77 + "dist-tags": { latest: string }; 78 + } 79 + )["dist-tags"].latest; 80 + 81 + // The format of the workerd version is `major.yyyymmdd.patch`. 82 + const match = latestWorkerdVersion.match(/\d+\.(\d{4})(\d{2})(\d{2})\.\d+/); 83 + 84 + if (match) { 85 + const [, year, month, date] = match; 86 + const compatDate = `${year}-${month}-${date}`; 87 + 88 + return compatDate; 89 + } 90 + } catch { 91 + /* empty */ 92 + } 93 + } 94 + 95 + /** 96 + * Creates a `open-next.config.ts` file for the user if it doesn't exist, but only after asking for the user's confirmation. 97 + * 98 + * If the user refuses an error is thrown (since the file is mandatory). 99 + * 100 + * @param projectOpts The options for the project 101 + */ 102 + export async function createOpenNextConfigIfNotExistent(projectOpts: ProjectOptions): Promise<void> { 103 + const openNextConfigPath = join(projectOpts.sourceDir, "open-next.config.ts"); 104 + 105 + if (!existsSync(openNextConfigPath)) { 106 + const answer = await askConfirmation( 107 + "Missing required `open-next.config.ts` file, do you want to create one?" 108 + ); 109 + 110 + if (!answer) { 111 + throw new Error("The `open-next.config.ts` file is required, aborting!"); 112 + } 113 + 114 + cpSync(join(getPackageTemplatesDirPath(), "defaults", "open-next.config.ts"), openNextConfigPath); 115 + } 116 + }
+53
packages/cloudflare/src/cli/build/utils/ensure-cf-config.ts
··· 1 + import type { OpenNextConfig } from "@opennextjs/aws/types/open-next.js"; 2 + 3 + /** 4 + * Ensures open next is configured for cloudflare. 5 + * 6 + * @param config OpenNext configuration. 7 + */ 8 + export function ensureCloudflareConfig(config: OpenNextConfig) { 9 + const requirements = { 10 + dftUseCloudflareWrapper: config.default?.override?.wrapper === "cloudflare-node", 11 + dftUseEdgeConverter: config.default?.override?.converter === "edge", 12 + dftMaybeUseCache: 13 + config.default?.override?.incrementalCache === "dummy" || 14 + typeof config.default?.override?.incrementalCache === "function", 15 + dftUseDummyTagCacheAndQueue: 16 + config.default?.override?.tagCache === "dummy" && config.default?.override?.queue === "dummy", 17 + disableCacheInterception: config.dangerous?.enableCacheInterception !== true, 18 + mwIsMiddlewareExternal: config.middleware?.external == true, 19 + mwUseCloudflareWrapper: config.middleware?.override?.wrapper === "cloudflare-edge", 20 + mwUseEdgeConverter: config.middleware?.override?.converter === "edge", 21 + mwUseFetchProxy: config.middleware?.override?.proxyExternalRequest === "fetch", 22 + }; 23 + 24 + if (Object.values(requirements).some((satisfied) => !satisfied)) { 25 + throw new Error( 26 + "The `open-next.config.ts` should have a default export like this:\n\n" + 27 + `{ 28 + default: { 29 + override: { 30 + wrapper: "cloudflare-node", 31 + converter: "edge", 32 + incrementalCache: "dummy" | function, 33 + tagCache: "dummy", 34 + queue: "dummy", 35 + }, 36 + }, 37 + 38 + middleware: { 39 + external: true, 40 + override: { 41 + wrapper: "cloudflare-edge", 42 + converter: "edge", 43 + proxyExternalRequest: "fetch", 44 + }, 45 + }, 46 + 47 + "dangerous": { 48 + "enableCacheInterception": false 49 + }, 50 + }\n\n`.replace(/^ {8}/gm, "") 51 + ); 52 + } 53 + }
+1 -1
packages/cloudflare/src/cli/build/utils/extract-project-env-vars.spec.ts
··· 4 4 import mockFs from "mock-fs"; 5 5 import { afterEach, beforeEach, describe, expect, it } from "vitest"; 6 6 7 - import { extractProjectEnvVars } from "./extract-project-env-vars"; 7 + import { extractProjectEnvVars } from "./extract-project-env-vars.js"; 8 8 9 9 const options = { monorepoRoot: "", appPath: "" } as BuildOptions; 10 10
+3
packages/cloudflare/src/cli/build/utils/index.ts
··· 1 + export * from "./apply-patches.js"; 2 + export * from "./create-config-files.js"; 3 + export * from "./ensure-cf-config.js"; 1 4 export * from "./extract-project-env-vars.js"; 2 5 export * from "./normalize-path.js"; 3 6 export * from "./ts-parse-file.js";
+1 -1
packages/cloudflare/src/cli/index.ts
··· 2 2 import { resolve } from "node:path"; 3 3 4 4 import { getArgs } from "./args.js"; 5 - import { build } from "./build/index.js"; 5 + import { build } from "./build/build.js"; 6 6 7 7 const nextAppDir = process.cwd(); 8 8