@opennextjs/cloudflare 1.16.6 → 1.17.1
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/dist/cli/build/build.js +1 -1
- package/dist/cli/build/bundle-server.js +3 -1
- package/dist/cli/build/open-next/compile-env-files.js +1 -1
- package/dist/cli/build/open-next/createServerBundle.js +1 -1
- package/dist/cli/build/patches/plugins/dynamic-requires.js +1 -1
- package/dist/cli/build/patches/plugins/instrumentation.js +1 -1
- package/dist/cli/build/patches/plugins/load-manifest.js +1 -1
- package/dist/cli/build/patches/plugins/next-server.js +1 -1
- package/dist/cli/build/patches/plugins/route-module.js +1 -1
- package/dist/cli/build/patches/plugins/wrangler-external.js +1 -1
- package/dist/cli/build/utils/index.d.ts +0 -6
- package/dist/cli/build/utils/index.js +1 -6
- package/dist/cli/commands/build.d.ts +13 -0
- package/dist/cli/commands/build.js +16 -4
- package/dist/cli/commands/deploy.d.ts +1 -1
- package/dist/cli/commands/deploy.js +9 -4
- package/dist/cli/commands/migrate.js +16 -8
- package/dist/cli/commands/populate-cache.d.ts +2 -2
- package/dist/cli/commands/populate-cache.js +19 -7
- package/dist/cli/commands/preview.d.ts +1 -1
- package/dist/cli/commands/preview.js +9 -4
- package/dist/cli/commands/skew-protection.d.ts +1 -1
- package/dist/cli/commands/upload.d.ts +1 -1
- package/dist/cli/commands/upload.js +9 -4
- package/dist/cli/commands/{helpers.js → utils/helpers.js} +1 -1
- package/dist/cli/commands/utils/run-wrangler.d.ts +44 -0
- package/dist/cli/{utils → commands/utils}/run-wrangler.js +46 -11
- package/dist/cli/commands/{utils.d.ts → utils/utils.d.ts} +6 -12
- package/dist/cli/commands/{utils.js → utils/utils.js} +14 -26
- package/dist/cli/project-options.d.ts +1 -1
- package/dist/cli/templates/images.d.ts +30 -0
- package/dist/cli/templates/images.js +130 -13
- package/dist/cli/templates/worker.js +2 -9
- package/dist/cli/utils/ask-account-selection.d.ts +12 -0
- package/dist/cli/utils/ask-account-selection.js +23 -0
- package/dist/cli/utils/create-open-next-config.d.ts +17 -0
- package/dist/cli/utils/create-open-next-config.js +50 -0
- package/dist/cli/utils/create-wrangler-config.d.ts +24 -0
- package/dist/cli/utils/create-wrangler-config.js +244 -0
- package/dist/cli/utils/nextjs-support.d.ts +10 -0
- package/dist/cli/utils/nextjs-support.js +24 -0
- package/package.json +3 -2
- package/templates/open-next.config.ts +1 -1
- package/templates/wrangler.jsonc +2 -2
- package/dist/cli/build/utils/create-config-files.d.ts +0 -19
- package/dist/cli/build/utils/create-config-files.js +0 -44
- package/dist/cli/utils/open-next-config.d.ts +0 -14
- package/dist/cli/utils/open-next-config.js +0 -27
- package/dist/cli/utils/run-wrangler.d.ts +0 -12
- package/dist/cli/utils/wrangler-config.d.ts +0 -15
- package/dist/cli/utils/wrangler-config.js +0 -64
- /package/dist/cli/{build → commands}/utils/files.d.ts +0 -0
- /package/dist/cli/{build → commands}/utils/files.js +0 -0
- /package/dist/cli/commands/{helpers.d.ts → utils/helpers.d.ts} +0 -0
- /package/dist/cli/{build/utils → utils}/extract-project-env-vars.d.ts +0 -0
- /package/dist/cli/{build/utils → utils}/extract-project-env-vars.js +0 -0
- /package/dist/cli/{build/utils → utils}/normalize-path.d.ts +0 -0
- /package/dist/cli/{build/utils → utils}/normalize-path.js +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { findPackagerAndRoot } from "@opennextjs/aws/build/helper.js";
|
|
5
|
+
import Cloudflare from "cloudflare";
|
|
6
|
+
import { parse, stringify } from "comment-json";
|
|
7
|
+
import { getPackageTemplatesDirPath } from "../../utils/get-package-templates-dir-path.js";
|
|
8
|
+
import { runWrangler } from "../commands/utils/run-wrangler.js";
|
|
9
|
+
import { askAccountSelection } from "./ask-account-selection.js";
|
|
10
|
+
/**
|
|
11
|
+
* Gets the path to the Wrangler configuration file if it exists.
|
|
12
|
+
*
|
|
13
|
+
* @param appDir The directory to check for the Wrangler config file
|
|
14
|
+
* @returns The path to Wrangler config file if it exists, undefined otherwise
|
|
15
|
+
*/
|
|
16
|
+
export function findWranglerConfig(appDir) {
|
|
17
|
+
const possibleExts = ["toml", "json", "jsonc"];
|
|
18
|
+
for (const ext of possibleExts) {
|
|
19
|
+
const path = join(appDir, `wrangler.${ext}`);
|
|
20
|
+
if (existsSync(path)) {
|
|
21
|
+
return path;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates a wrangler.jsonc config file in the target directory for the project.
|
|
28
|
+
*
|
|
29
|
+
* If a wrangler.jsonc file already exists it will be overridden.
|
|
30
|
+
*
|
|
31
|
+
* The function attempts to create an R2 bucket for incremental cache. If bucket creation
|
|
32
|
+
* fails (e.g., user not authenticated or R2 not enabled), a configuration without caching
|
|
33
|
+
* will be created instead.
|
|
34
|
+
*
|
|
35
|
+
* @param projectDir The target directory for the project
|
|
36
|
+
* @param defaultCompatDate The default YYYY-MM-DD compatibility date to use in the config (used if fetching the latest workerd version date fails)
|
|
37
|
+
* @returns An object containing a `cachingEnabled` which indicates whether caching has been set up during the wrangler
|
|
38
|
+
* config file creation or not
|
|
39
|
+
*/
|
|
40
|
+
export async function createWranglerConfigFile(projectDir, defaultCompatDate = "2026-02-01") {
|
|
41
|
+
const workerName = getWorkerName(projectDir);
|
|
42
|
+
const compatibilityDate = (await getLatestCompatDate()) ?? defaultCompatDate;
|
|
43
|
+
const wranglerConfigStr = readFileSync(join(getPackageTemplatesDirPath(), "wrangler.jsonc"), "utf8")
|
|
44
|
+
.replaceAll("<WORKER_NAME>", workerName)
|
|
45
|
+
.replaceAll("<COMPATIBILITY_DATE>", compatibilityDate);
|
|
46
|
+
const wranglerConfig = parse(wranglerConfigStr);
|
|
47
|
+
assert(Array.isArray(wranglerConfig.r2_buckets));
|
|
48
|
+
assert(wranglerConfig.r2_buckets[0] != null && typeof wranglerConfig.r2_buckets[0] === "object");
|
|
49
|
+
assert("bucket_name" in wranglerConfig.r2_buckets[0] &&
|
|
50
|
+
typeof wranglerConfig.r2_buckets[0].bucket_name === "string");
|
|
51
|
+
const bucketName = wranglerConfig.r2_buckets[0].bucket_name;
|
|
52
|
+
const { success: cachingEnabled } = await maybeCreateR2Bucket(projectDir, bucketName);
|
|
53
|
+
if (!cachingEnabled) {
|
|
54
|
+
delete wranglerConfig.r2_buckets;
|
|
55
|
+
}
|
|
56
|
+
writeFileSync(join(projectDir, "wrangler.jsonc"), stringify(wranglerConfig, null, "\t"));
|
|
57
|
+
return { cachingEnabled };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets a valid worker name from the project's package.json name, falling back to `app-name`
|
|
61
|
+
* in case the name could not be detected.
|
|
62
|
+
*
|
|
63
|
+
* @param projectDir The project directory containing the package.json file
|
|
64
|
+
* @returns A valid worker name suitable for a Cloudflare Worker
|
|
65
|
+
*/
|
|
66
|
+
function getWorkerName(projectDir) {
|
|
67
|
+
const appName = getNameFromPackageJson(projectDir) ?? "app-name";
|
|
68
|
+
return (appName
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
// Remove org prefix if present (e.g., "@org/my-app" -> "my-app")
|
|
71
|
+
.replace(/^@[^/]+\//, "")
|
|
72
|
+
.replaceAll("_", "-")
|
|
73
|
+
.replace(/[^a-z0-9-]/g, ""));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Reads the `name` field from the `package.json` in the given directory.
|
|
77
|
+
*
|
|
78
|
+
* @param sourceDir - The directory containing the `package.json` file.
|
|
79
|
+
* @returns The package name if found, `undefined` otherwise.
|
|
80
|
+
*/
|
|
81
|
+
function getNameFromPackageJson(sourceDir) {
|
|
82
|
+
try {
|
|
83
|
+
const packageJsonStr = readFileSync(join(sourceDir, "package.json"), "utf8");
|
|
84
|
+
const packageJson = JSON.parse(packageJsonStr);
|
|
85
|
+
if (typeof packageJson.name === "string")
|
|
86
|
+
return packageJson.name;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* empty */
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Fetches the latest compatibility date from the npm registry based on the latest `workerd` version.
|
|
94
|
+
*
|
|
95
|
+
* The workerd version format is `major.yyyymmdd.patch`. The date portion is extracted and formatted
|
|
96
|
+
* as `YYYY-MM-DD`. If the extracted date is in the future, today's date is returned instead.
|
|
97
|
+
*
|
|
98
|
+
* @returns The compatibility date as a `YYYY-MM-DD` string, or `undefined` if the fetch or parsing fails.
|
|
99
|
+
*/
|
|
100
|
+
async function getLatestCompatDate() {
|
|
101
|
+
try {
|
|
102
|
+
const resp = await fetch(`https://registry.npmjs.org/workerd`);
|
|
103
|
+
const latestWorkerdVersion = (await resp.json())["dist-tags"].latest;
|
|
104
|
+
// The format of the workerd version is `major.yyyymmdd.patch`.
|
|
105
|
+
const match = latestWorkerdVersion.match(/\d+\.(\d{4})(\d{2})(\d{2})\.\d+/);
|
|
106
|
+
if (match) {
|
|
107
|
+
const [, year, month, day] = match;
|
|
108
|
+
const compatDate = `${year}-${month}-${day}`;
|
|
109
|
+
const currentDate = new Date().toISOString().slice(0, 10);
|
|
110
|
+
return compatDate < currentDate ? compatDate : currentDate;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
/* empty */
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Gets the authentication credentials for Cloudflare API calls.
|
|
119
|
+
*
|
|
120
|
+
* Uses `wrangler auth token --json` which checks the following sources in order:
|
|
121
|
+
* 1. CLOUDFLARE_API_TOKEN environment variable
|
|
122
|
+
* 2. CLOUDFLARE_API_KEY + CLOUDFLARE_EMAIL environment variables
|
|
123
|
+
* 3. OAuth token from `wrangler login`
|
|
124
|
+
*
|
|
125
|
+
* @param options The build options containing packager and monorepo root
|
|
126
|
+
* @returns The auth credentials if available, undefined otherwise
|
|
127
|
+
*/
|
|
128
|
+
function getAuthCredentials(options) {
|
|
129
|
+
const result = runWrangler(options, ["auth", "token", "--json"], { logging: "none" });
|
|
130
|
+
if (!result.success) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const json = JSON.parse(result.stdout);
|
|
135
|
+
if (json.type === "api_key") {
|
|
136
|
+
return { type: "api_key", apiKey: json.key, apiEmail: json.email };
|
|
137
|
+
}
|
|
138
|
+
// Both "oauth" and "api_token" types have a token field
|
|
139
|
+
if (json.token) {
|
|
140
|
+
return { type: "token", token: json.token };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
/* empty */
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the account ID for Cloudflare API calls.
|
|
150
|
+
*
|
|
151
|
+
* Tries the following sources in order:
|
|
152
|
+
* 1. CLOUDFLARE_ACCOUNT_ID or CF_ACCOUNT_ID environment variable
|
|
153
|
+
* 2. List accounts using the SDK and return the first one
|
|
154
|
+
*
|
|
155
|
+
* @param client The Cloudflare SDK client
|
|
156
|
+
* @returns The account ID if available, undefined otherwise
|
|
157
|
+
*/
|
|
158
|
+
async function getAccountId(client) {
|
|
159
|
+
if (process.env.CLOUDFLARE_ACCOUNT_ID || process.env.CF_ACCOUNT_ID) {
|
|
160
|
+
return process.env.CLOUDFLARE_ACCOUNT_ID || process.env.CF_ACCOUNT_ID;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const accountsList = await client.accounts.list();
|
|
164
|
+
const accounts = [];
|
|
165
|
+
for await (const account of accountsList) {
|
|
166
|
+
accounts.push({ id: account.id, name: account.name });
|
|
167
|
+
}
|
|
168
|
+
if (accounts.length === 0) {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
if (accounts.length === 1 && accounts[0]) {
|
|
172
|
+
return accounts[0].id;
|
|
173
|
+
}
|
|
174
|
+
return await askAccountSelection(accounts);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
/* empty */
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Attempts to log in to Cloudflare via wrangler.
|
|
183
|
+
*
|
|
184
|
+
* @param options The build options containing packager and monorepo root
|
|
185
|
+
* @returns true if login was successful, false otherwise
|
|
186
|
+
*/
|
|
187
|
+
function wranglerLogin(options) {
|
|
188
|
+
const result = runWrangler(options, ["login"], { logging: "all" });
|
|
189
|
+
return result.success;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Creates an R2 bucket.
|
|
193
|
+
*
|
|
194
|
+
* If no auth credentials are available, falls back to wrangler login for OAuth authentication.
|
|
195
|
+
*
|
|
196
|
+
* @param projectDir The project directory to detect the package manager
|
|
197
|
+
* @param bucketName The name of the R2 bucket to create
|
|
198
|
+
* @returns An object indicating success with the bucket name, or failure
|
|
199
|
+
*/
|
|
200
|
+
async function maybeCreateR2Bucket(projectDir, bucketName) {
|
|
201
|
+
try {
|
|
202
|
+
const { packager, root: monorepoRoot } = findPackagerAndRoot(projectDir);
|
|
203
|
+
const options = { packager, monorepoRoot };
|
|
204
|
+
let authCredentials = getAuthCredentials(options);
|
|
205
|
+
// If no credentials available, fall back to wrangler login
|
|
206
|
+
if (!authCredentials) {
|
|
207
|
+
const loginSuccess = wranglerLogin(options);
|
|
208
|
+
if (!loginSuccess) {
|
|
209
|
+
return { success: false };
|
|
210
|
+
}
|
|
211
|
+
// Get credentials after login
|
|
212
|
+
authCredentials = getAuthCredentials(options);
|
|
213
|
+
if (!authCredentials) {
|
|
214
|
+
return { success: false };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const client = authCredentials.type === "api_key"
|
|
218
|
+
? new Cloudflare({ apiKey: authCredentials.apiKey, apiEmail: authCredentials.apiEmail })
|
|
219
|
+
: new Cloudflare({ apiToken: authCredentials.token });
|
|
220
|
+
const accountId = await getAccountId(client);
|
|
221
|
+
if (!accountId) {
|
|
222
|
+
return { success: false };
|
|
223
|
+
}
|
|
224
|
+
// Check if bucket already exists
|
|
225
|
+
try {
|
|
226
|
+
await client.r2.buckets.get(bucketName, { account_id: accountId });
|
|
227
|
+
// Bucket exists
|
|
228
|
+
return { success: true, bucketName };
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
if (!(error instanceof Cloudflare.NotFoundError)) {
|
|
232
|
+
return { success: false };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
await client.r2.buckets.create({
|
|
236
|
+
account_id: accountId,
|
|
237
|
+
name: bucketName,
|
|
238
|
+
});
|
|
239
|
+
return { success: true, bucketName };
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return { success: false };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as buildHelper from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that the Next.js version is supported and checks wrangler compatibility.
|
|
4
|
+
*
|
|
5
|
+
* Note: this function assumes that wrangler is installed.
|
|
6
|
+
*
|
|
7
|
+
* @param options.nextVersion The detected Next.js version string
|
|
8
|
+
* @throws {Error} If the Next.js version is unsupported
|
|
9
|
+
*/
|
|
10
|
+
export declare function ensureNextjsVersionSupported({ nextVersion, }: Pick<buildHelper.BuildOptions, "nextVersion">): Promise<void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as buildHelper from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
import logger from "@opennextjs/aws/logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* Validates that the Next.js version is supported and checks wrangler compatibility.
|
|
5
|
+
*
|
|
6
|
+
* Note: this function assumes that wrangler is installed.
|
|
7
|
+
*
|
|
8
|
+
* @param options.nextVersion The detected Next.js version string
|
|
9
|
+
* @throws {Error} If the Next.js version is unsupported
|
|
10
|
+
*/
|
|
11
|
+
export async function ensureNextjsVersionSupported({ nextVersion, }) {
|
|
12
|
+
if (buildHelper.compareSemver(nextVersion, "<", "14.2.0")) {
|
|
13
|
+
throw new Error("Next.js version unsupported, please upgrade to version 14.2 or greater.");
|
|
14
|
+
}
|
|
15
|
+
const { default: { version: wranglerVersion }, } = await import("wrangler/package.json", { with: { type: "json" } });
|
|
16
|
+
// We need a version of workerd that has a fix for setImmediate for Next.js 16.1+
|
|
17
|
+
// See:
|
|
18
|
+
// - https://github.com/cloudflare/workerd/pull/5869
|
|
19
|
+
// - https://github.com/opennextjs/opennextjs-cloudflare/issues/1049
|
|
20
|
+
if (buildHelper.compareSemver(nextVersion, ">=", "16.1.0") &&
|
|
21
|
+
buildHelper.compareSemver(wranglerVersion, "<", "4.59.2")) {
|
|
22
|
+
logger.warn(`Next.js 16.1+ requires wrangler 4.59.2 or greater (${wranglerVersion} detected).`);
|
|
23
|
+
}
|
|
24
|
+
}
|
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": "1.
|
|
4
|
+
"version": "1.17.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opennextjs-cloudflare": "dist/cli/index.js"
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"cloudflare": "^4.4.1",
|
|
49
49
|
"enquirer": "^2.4.1",
|
|
50
50
|
"glob": "^12.0.0",
|
|
51
|
+
"comment-json": "^4.5.1",
|
|
51
52
|
"ts-tqdm": "^0.8.6",
|
|
52
53
|
"yargs": "^18.0.0"
|
|
53
54
|
},
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"vitest": "^2.1.1"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
|
-
"wrangler": "^4.
|
|
79
|
+
"wrangler": "^4.65.0",
|
|
79
80
|
"next": "~15.0.8 || ~15.1.12 || ~15.2.9 || ~15.3.9 || ~15.4.11 || ~15.5.10 || ~16.0.11 || ^16.1.5"
|
|
80
81
|
},
|
|
81
82
|
"scripts": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// default open-next.config.ts file created by @opennextjs/cloudflare
|
|
2
|
-
import { defineCloudflareConfig } from "@opennextjs/cloudflare
|
|
2
|
+
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
|
|
3
3
|
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
|
|
4
4
|
|
|
5
5
|
export default defineCloudflareConfig({
|
package/templates/wrangler.jsonc
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "node_modules/wrangler/config-schema.json",
|
|
3
3
|
"main": ".open-next/worker.js",
|
|
4
4
|
"name": "<WORKER_NAME>",
|
|
5
|
-
"compatibility_date": "
|
|
5
|
+
"compatibility_date": "<COMPATIBILITY_DATE>",
|
|
6
6
|
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
|
|
7
7
|
"assets": {
|
|
8
8
|
"directory": ".open-next/assets",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// Create the bucket before deploying
|
|
25
25
|
// You can change the bucket name if you want
|
|
26
26
|
// See https://developers.cloudflare.com/workers/wrangler/commands/#r2-bucket-create
|
|
27
|
-
"bucket_name": "cache"
|
|
27
|
+
"bucket_name": "<WORKER_NAME>-opennext-cache"
|
|
28
28
|
}
|
|
29
29
|
],
|
|
30
30
|
"images": {
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ProjectOptions } from "../../project-options.js";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a `wrangler.jsonc` file for the user if a wrangler config file doesn't already exist,
|
|
4
|
-
* but only after asking for the user's confirmation.
|
|
5
|
-
*
|
|
6
|
-
* If the user refuses a warning is shown (which offers ways to opt out of this check to the user).
|
|
7
|
-
*
|
|
8
|
-
* @param projectOpts The options for the project
|
|
9
|
-
*/
|
|
10
|
-
export declare function createWranglerConfigIfNonExistent(projectOpts: ProjectOptions): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* Creates a `open-next.config.ts` file for the user if it doesn't exist, but only after asking for the user's confirmation.
|
|
13
|
-
*
|
|
14
|
-
* If the user refuses an error is thrown (since the file is mandatory).
|
|
15
|
-
*
|
|
16
|
-
* @param sourceDir The source directory for the project
|
|
17
|
-
* @return The path to the created source file
|
|
18
|
-
*/
|
|
19
|
-
export declare function createOpenNextConfigIfNotExistent(sourceDir: string): Promise<string>;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { askConfirmation } from "../../utils/ask-confirmation.js";
|
|
2
|
-
import { createOpenNextConfigFile, findOpenNextConfig } from "../../utils/open-next-config.js";
|
|
3
|
-
import { createWranglerConfigFile, findWranglerConfig } from "../../utils/wrangler-config.js";
|
|
4
|
-
/**
|
|
5
|
-
* Creates a `wrangler.jsonc` file for the user if a wrangler config file doesn't already exist,
|
|
6
|
-
* but only after asking for the user's confirmation.
|
|
7
|
-
*
|
|
8
|
-
* If the user refuses a warning is shown (which offers ways to opt out of this check to the user).
|
|
9
|
-
*
|
|
10
|
-
* @param projectOpts The options for the project
|
|
11
|
-
*/
|
|
12
|
-
export async function createWranglerConfigIfNonExistent(projectOpts) {
|
|
13
|
-
const wranglerConfigFileExists = Boolean(findWranglerConfig(projectOpts.sourceDir));
|
|
14
|
-
if (wranglerConfigFileExists) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
const answer = await askConfirmation("No `wrangler.(toml|json|jsonc)` config file found, do you want to create one?");
|
|
18
|
-
if (!answer) {
|
|
19
|
-
console.warn("No Wrangler config file created" +
|
|
20
|
-
"\n" +
|
|
21
|
-
"(to avoid this check use the `--skipWranglerConfigCheck` flag or set a `SKIP_WRANGLER_CONFIG_CHECK` environment variable to `yes`)");
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
await createWranglerConfigFile(projectOpts.sourceDir);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Creates a `open-next.config.ts` file for the user if it doesn't exist, but only after asking for the user's confirmation.
|
|
28
|
-
*
|
|
29
|
-
* If the user refuses an error is thrown (since the file is mandatory).
|
|
30
|
-
*
|
|
31
|
-
* @param sourceDir The source directory for the project
|
|
32
|
-
* @return The path to the created source file
|
|
33
|
-
*/
|
|
34
|
-
export async function createOpenNextConfigIfNotExistent(sourceDir) {
|
|
35
|
-
const openNextConfigPath = findOpenNextConfig(sourceDir);
|
|
36
|
-
if (!openNextConfigPath) {
|
|
37
|
-
const answer = await askConfirmation("Missing required `open-next.config.ts` file, do you want to create one?");
|
|
38
|
-
if (!answer) {
|
|
39
|
-
throw new Error("The `open-next.config.ts` file is required, aborting!");
|
|
40
|
-
}
|
|
41
|
-
return createOpenNextConfigFile(sourceDir);
|
|
42
|
-
}
|
|
43
|
-
return openNextConfigPath;
|
|
44
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Finds the path to the OpenNext configuration file if it exists.
|
|
3
|
-
*
|
|
4
|
-
* @param appDir The directory to check for the open-next.config.ts file
|
|
5
|
-
* @returns The full path to open-next.config.ts if it exists, undefined otherwise
|
|
6
|
-
*/
|
|
7
|
-
export declare function findOpenNextConfig(appDir: string): string | undefined;
|
|
8
|
-
/**
|
|
9
|
-
* Creates a `open-next.config.ts` file in the target directory for the project.
|
|
10
|
-
*
|
|
11
|
-
* @param appDir The Next application root
|
|
12
|
-
* @return The path to the created source file
|
|
13
|
-
*/
|
|
14
|
-
export declare function createOpenNextConfigFile(appDir: string): Promise<string>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { cpSync, existsSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { getPackageTemplatesDirPath } from "../../utils/get-package-templates-dir-path.js";
|
|
4
|
-
/**
|
|
5
|
-
* Finds the path to the OpenNext configuration file if it exists.
|
|
6
|
-
*
|
|
7
|
-
* @param appDir The directory to check for the open-next.config.ts file
|
|
8
|
-
* @returns The full path to open-next.config.ts if it exists, undefined otherwise
|
|
9
|
-
*/
|
|
10
|
-
export function findOpenNextConfig(appDir) {
|
|
11
|
-
const openNextConfigPath = join(appDir, "open-next.config.ts");
|
|
12
|
-
if (existsSync(openNextConfigPath)) {
|
|
13
|
-
return openNextConfigPath;
|
|
14
|
-
}
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Creates a `open-next.config.ts` file in the target directory for the project.
|
|
19
|
-
*
|
|
20
|
-
* @param appDir The Next application root
|
|
21
|
-
* @return The path to the created source file
|
|
22
|
-
*/
|
|
23
|
-
export async function createOpenNextConfigFile(appDir) {
|
|
24
|
-
const openNextConfigPath = join(appDir, "open-next.config.ts");
|
|
25
|
-
cpSync(join(getPackageTemplatesDirPath(), "open-next.config.ts"), openNextConfigPath);
|
|
26
|
-
return openNextConfigPath;
|
|
27
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
-
export type WranglerTarget = "local" | "remote";
|
|
3
|
-
type WranglerOptions = {
|
|
4
|
-
target?: WranglerTarget;
|
|
5
|
-
environment?: string;
|
|
6
|
-
configPath?: string;
|
|
7
|
-
logging?: "all" | "error";
|
|
8
|
-
env?: Record<string, string>;
|
|
9
|
-
};
|
|
10
|
-
export declare function runWrangler(options: BuildOptions, args: string[], wranglerOpts?: WranglerOptions): void;
|
|
11
|
-
export declare function isWranglerTarget(v: string | undefined): v is WranglerTarget;
|
|
12
|
-
export {};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gets the path to the Wrangler configuration file if it exists.
|
|
3
|
-
*
|
|
4
|
-
* @param appDir The directory to check for the Wrangler config file
|
|
5
|
-
* @returns The path to Wrangler config file if it exists, undefined otherwise
|
|
6
|
-
*/
|
|
7
|
-
export declare function findWranglerConfig(appDir: string): string | undefined;
|
|
8
|
-
/**
|
|
9
|
-
* Creates a wrangler.jsonc config file in the target directory for the project.
|
|
10
|
-
*
|
|
11
|
-
* If a wrangler.jsonc file already exists it will be overridden.
|
|
12
|
-
*
|
|
13
|
-
* @param projectDir The target directory for the project
|
|
14
|
-
*/
|
|
15
|
-
export declare function createWranglerConfigFile(projectDir: string): Promise<void>;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { getPackageTemplatesDirPath } from "../../utils/get-package-templates-dir-path.js";
|
|
4
|
-
/**
|
|
5
|
-
* Gets the path to the Wrangler configuration file if it exists.
|
|
6
|
-
*
|
|
7
|
-
* @param appDir The directory to check for the Wrangler config file
|
|
8
|
-
* @returns The path to Wrangler config file if it exists, undefined otherwise
|
|
9
|
-
*/
|
|
10
|
-
export function findWranglerConfig(appDir) {
|
|
11
|
-
const possibleExts = ["toml", "json", "jsonc"];
|
|
12
|
-
for (const ext of possibleExts) {
|
|
13
|
-
const path = join(appDir, `wrangler.${ext}`);
|
|
14
|
-
if (existsSync(path)) {
|
|
15
|
-
return path;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Creates a wrangler.jsonc config file in the target directory for the project.
|
|
22
|
-
*
|
|
23
|
-
* If a wrangler.jsonc file already exists it will be overridden.
|
|
24
|
-
*
|
|
25
|
-
* @param projectDir The target directory for the project
|
|
26
|
-
*/
|
|
27
|
-
export async function createWranglerConfigFile(projectDir) {
|
|
28
|
-
let wranglerConfig = readFileSync(join(getPackageTemplatesDirPath(), "wrangler.jsonc"), "utf8");
|
|
29
|
-
const appName = getAppNameFromPackageJson(projectDir) ?? "app-name";
|
|
30
|
-
wranglerConfig = wranglerConfig.replaceAll('"<WORKER_NAME>"', JSON.stringify(appName.replaceAll("_", "-")));
|
|
31
|
-
const compatDate = await getLatestCompatDate();
|
|
32
|
-
if (compatDate) {
|
|
33
|
-
wranglerConfig = wranglerConfig.replace(/"compatibility_date": "\d{4}-\d{2}-\d{2}"/, `"compatibility_date": ${JSON.stringify(compatDate)}`);
|
|
34
|
-
}
|
|
35
|
-
writeFileSync(join(projectDir, "wrangler.jsonc"), wranglerConfig);
|
|
36
|
-
}
|
|
37
|
-
function getAppNameFromPackageJson(sourceDir) {
|
|
38
|
-
try {
|
|
39
|
-
const packageJsonStr = readFileSync(join(sourceDir, "package.json"), "utf8");
|
|
40
|
-
const packageJson = JSON.parse(packageJsonStr);
|
|
41
|
-
if (typeof packageJson.name === "string")
|
|
42
|
-
return packageJson.name;
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
/* empty */
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function getLatestCompatDate() {
|
|
49
|
-
try {
|
|
50
|
-
const resp = await fetch(`https://registry.npmjs.org/workerd`);
|
|
51
|
-
const latestWorkerdVersion = (await resp.json())["dist-tags"].latest;
|
|
52
|
-
// The format of the workerd version is `major.yyyymmdd.patch`.
|
|
53
|
-
const match = latestWorkerdVersion.match(/\d+\.(\d{4})(\d{2})(\d{2})\.\d+/);
|
|
54
|
-
if (match) {
|
|
55
|
-
const [, year, month, day] = match;
|
|
56
|
-
const compatDate = `${year}-${month}-${day}`;
|
|
57
|
-
const currentDate = new Date().toISOString().slice(0, 10);
|
|
58
|
-
return compatDate < currentDate ? compatDate : currentDate;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
/* empty */
|
|
63
|
-
}
|
|
64
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|