Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lucky-places-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/cloudflare": patch
---

refactor: deprecate usage of the `--configPath` flag for the Wrangler config, in favour of the `--config` flag.
5 changes: 5 additions & 0 deletions .changeset/real-bats-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/cloudflare": minor
---

feat: support for a custom OpenNext config path with the `--openNextConfigPath` flag
2 changes: 1 addition & 1 deletion examples/overrides/r2-incremental-cache/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"build:worker": "pnpm opennextjs-cloudflare build",
"build:worker": "pnpm opennextjs-cloudflare build --openNextConfigPath=./.custom-config/my-opennext-config.ts",
"preview:worker": "pnpm opennextjs-cloudflare preview",
"preview": "pnpm build:worker && pnpm preview:worker",
"e2e": "playwright test -c e2e/playwright.config.ts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ export async function getLatestCompatDate(): Promise<string | undefined> {
* If the user refuses an error is thrown (since the file is mandatory).
*
* @param sourceDir The source directory for the project
* @return The path to the created source file
*/
export async function createOpenNextConfigIfNotExistent(sourceDir: string): Promise<void> {
export async function createOpenNextConfigIfNotExistent(sourceDir: string): Promise<string> {
const openNextConfigPath = join(sourceDir, "open-next.config.ts");

if (!existsSync(openNextConfigPath)) {
Expand All @@ -108,4 +109,6 @@ export async function createOpenNextConfigIfNotExistent(sourceDir: string): Prom

cpSync(join(getPackageTemplatesDirPath(), "open-next.config.ts"), openNextConfigPath);
}

return openNextConfigPath;
}
7 changes: 6 additions & 1 deletion packages/cloudflare/src/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ async function buildCommand(
skipNextBuild: boolean;
noMinify: boolean;
skipWranglerConfigCheck: boolean;
openNextConfigPath: string | undefined;
}>
): Promise<void> {
printHeaders("build");

const { config, buildDir } = await compileConfig();
const { config, buildDir } = await compileConfig(args.openNextConfigPath);
const options = getNormalizedOptions(config, buildDir);

const wranglerConfig = readWranglerConfig(args);
Expand Down Expand Up @@ -65,6 +66,10 @@ export function addBuildCommand<T extends yargs.Argv>(y: T) {
type: "boolean",
default: ["1", "true", "yes"].includes(String(process.env.SKIP_WRANGLER_CONFIG_CHECK)),
desc: "Skip checking for a Wrangler config",
})
.option("openNextConfigPath", {
type: "string",
desc: "Path to the OpenNext configuration file",
}),
(args) => buildCommand(withWranglerPassthroughArgs(args))
);
Expand Down
4 changes: 2 additions & 2 deletions packages/cloudflare/src/cli/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function deployCommand(args: WithWranglerArgs<{ cacheChunkSize: num
const wranglerConfig = readWranglerConfig(args);

const envVars = await getEnvFromPlatformProxy({
configPath: args.configPath,
configPath: args.wranglerConfigPath,
environment: args.env,
});

Expand All @@ -37,7 +37,7 @@ export async function deployCommand(args: WithWranglerArgs<{ cacheChunkSize: num
await populateCache(options, config, wranglerConfig, {
target: "remote",
environment: args.env,
configPath: args.configPath,
wranglerConfigPath: args.wranglerConfigPath,
cacheChunkSize: args.cacheChunkSize,
});

Expand Down
10 changes: 5 additions & 5 deletions packages/cloudflare/src/cli/commands/populate-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function getCacheAssets(opts: BuildOptions): CacheAsset[] {
type PopulateCacheOptions = {
target: WranglerTarget;
environment?: string;
configPath?: string;
wranglerConfigPath?: string;
cacheChunkSize?: number;
};

Expand Down Expand Up @@ -148,7 +148,7 @@ async function populateR2IncrementalCache(
],
{
target: populateCacheOptions.target,
configPath: populateCacheOptions.configPath,
configPath: populateCacheOptions.wranglerConfigPath,
// R2 does not support the environment flag and results in the following error:
// Incorrect type for the 'cacheExpiry' field on 'HttpMetadata': the provided value is not of type 'date'.
environment: undefined,
Expand Down Expand Up @@ -200,7 +200,7 @@ async function populateKVIncrementalCache(
runWrangler(options, ["kv bulk put", quoteShellMeta(chunkPath), `--binding ${KV_CACHE_BINDING_NAME}`], {
target: populateCacheOptions.target,
environment: populateCacheOptions.environment,
configPath: populateCacheOptions.configPath,
configPath: populateCacheOptions.wranglerConfigPath,
logging: "error",
});

Expand Down Expand Up @@ -232,7 +232,7 @@ function populateD1TagCache(
{
target: populateCacheOptions.target,
environment: populateCacheOptions.environment,
configPath: populateCacheOptions.configPath,
configPath: populateCacheOptions.wranglerConfigPath,
logging: "error",
}
);
Expand Down Expand Up @@ -313,7 +313,7 @@ async function populateCacheCommand(
await populateCache(options, config, wranglerConfig, {
target,
environment: args.env,
configPath: args.configPath,
wranglerConfigPath: args.wranglerConfigPath,
cacheChunkSize: args.cacheChunkSize,
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/src/cli/commands/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function previewCommand(args: WithWranglerArgs<{ cacheChunkSize: nu
await populateCache(options, config, wranglerConfig, {
target: "local",
environment: args.env,
configPath: args.configPath,
wranglerConfigPath: args.wranglerConfigPath,
cacheChunkSize: args.cacheChunkSize,
});

Expand Down
4 changes: 2 additions & 2 deletions packages/cloudflare/src/cli/commands/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function uploadCommand(args: WithWranglerArgs<{ cacheChunkSize: num
const wranglerConfig = readWranglerConfig(args);

const envVars = await getEnvFromPlatformProxy({
configPath: args.configPath,
configPath: args.wranglerConfigPath,
environment: args.env,
});

Expand All @@ -37,7 +37,7 @@ export async function uploadCommand(args: WithWranglerArgs<{ cacheChunkSize: num
await populateCache(options, config, wranglerConfig, {
target: "remote",
environment: args.env,
configPath: args.configPath,
wranglerConfigPath: args.wranglerConfigPath,
cacheChunkSize: args.cacheChunkSize,
});

Expand Down
75 changes: 54 additions & 21 deletions packages/cloudflare/src/cli/commands/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { createOpenNextConfigIfNotExistent, ensureCloudflareConfig } from "../bu
export type WithWranglerArgs<T = unknown> = T & {
// Array of arguments that can be given to wrangler commands, including the `--config` and `--env` args.
wranglerArgs: string[];
configPath: string | undefined;
wranglerConfigPath: string | undefined;
env: string | undefined;
};

Expand All @@ -33,14 +33,27 @@ export function printHeaders(command: string) {
}

/**
* Compile the OpenNext config, and ensure it is for Cloudflare.
* Compile the OpenNext config.
*
* When users do not specify a custom config file (using `----openNextConfigPath`),
* the CLI will offer to create one.
*
* When users specify a custom config file but it doesn't exist, we throw an Error.
*
* @param configPath Optional path to the config file. Absolute or relative to cwd.
* @returns OpenNext config.
*/
export async function compileConfig() {
await createOpenNextConfigIfNotExistent(nextAppDir);
export async function compileConfig(configPath: string | undefined) {
if (configPath && !existsSync(configPath)) {
throw new Error(`Custom config file not found at ${configPath}`);
}

const { config, buildDir } = await compileOpenNextConfig(nextAppDir, undefined, { compileEdge: true });
if (!configPath) {
configPath = await createOpenNextConfigIfNotExistent(nextAppDir);
}

// TODO: remove the hack passing the `configPath` as the `baseDir` when https://github.com/opennextjs/opennextjs-aws/pull/972 is merged
const { config, buildDir } = await compileOpenNextConfig(configPath, "", { compileEdge: true });
ensureCloudflareConfig(config);

return { config, buildDir };
Expand Down Expand Up @@ -89,38 +102,57 @@ export function getNormalizedOptions(config: OpenNextConfig, buildDir = nextAppD
* @returns Wrangler config.
*/
export function readWranglerConfig(args: WithWranglerArgs) {
return unstable_readConfig({ env: args.env, config: args.configPath });
return unstable_readConfig({ env: args.env, config: args.wranglerConfigPath });
}

/**
* Adds flags for the wrangler config path and environment to the yargs configuration.
*/
export function withWranglerOptions<T extends yargs.Argv>(args: T) {
return args
.options("configPath", {
.option("config", {
type: "string",
alias: "c",
desc: "Path to Wrangler configuration file",
})
.option("configPath", {
type: "string",
alias: ["config", "c"],
desc: "Path to Wrangler configuration file",
deprecated: true,
})
.options("env", {
.option("env", {
type: "string",
alias: "e",
desc: "Wrangler environment to use for operations",
});
}

type WranglerInputArgs = {
configPath: string | undefined;
config: string | undefined;
env: string | undefined;
};

/**
*
* @param args
* @returns An array of arguments that can be given to wrangler commands, including the `--config` and `--env` args.
*/
function getWranglerArgs(args: {
_: (string | number)[];
configPath: string | undefined;
env: string | undefined;
}): string[] {
function getWranglerArgs(args: WranglerInputArgs & { _: (string | number)[] }): string[] {
if (args.configPath) {
logger.warn("The `--configPath` flag is deprecated, please use `--config` instead.");

if (args.config) {
logger.error(
"Multiple config flags found. Please use the `--config` flag for your Wrangler config path."
);
process.exit(1);
}
}

return [
...(args.configPath ? ["--config", args.configPath] : []),
...(args.config ? ["--config", args.config] : []),
...(args.env ? ["--env", args.env] : []),
// Note: the first args in `_` will be the commands.
...args._.slice(args._[0] === "populateCache" ? 2 : 1).map((a) => `${a}`),
Expand All @@ -132,11 +164,12 @@ function getWranglerArgs(args: {
* @param args
* @returns The inputted args, and an array of arguments that can be given to wrangler commands, including the `--config` and `--env` args.
*/
export function withWranglerPassthroughArgs<
T extends yargs.ArgumentsCamelCase<{
configPath: string | undefined;
env: string | undefined;
}>,
>(args: T) {
return { ...args, wranglerArgs: getWranglerArgs(args) };
export function withWranglerPassthroughArgs<T extends yargs.ArgumentsCamelCase<WranglerInputArgs>>(
args: T
): WithWranglerArgs<T> {
return {
...args,
wranglerConfigPath: args.config ?? args.configPath,
wranglerArgs: getWranglerArgs(args),
};
}