@opennextjs/cloudflare 1.8.2 → 1.8.4

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.
@@ -96,7 +96,7 @@ class RegionalCache {
96
96
  });
97
97
  }
98
98
  catch (e) {
99
- error(`Failed to get from regional cache`, e);
99
+ error(`Failed to set the regional cache`, e);
100
100
  }
101
101
  }
102
102
  async delete(key) {
@@ -87,19 +87,6 @@ interface DOIdOptions {
87
87
  replicaId?: number;
88
88
  region?: DurableObjectLocationHint;
89
89
  }
90
- export declare class DOId {
91
- options: DOIdOptions;
92
- shardId: string;
93
- replicaId: number;
94
- region?: DurableObjectLocationHint;
95
- constructor(options: DOIdOptions);
96
- private generateRandomNumberBetween;
97
- get key(): string;
98
- }
99
- interface CacheTagKeyOptions {
100
- doId: DOId;
101
- tags: string[];
102
- }
103
90
  declare class ShardedDOTagCache implements NextModeTagCache {
104
91
  private opts;
105
92
  readonly mode: "nextMode";
@@ -111,29 +98,9 @@ declare class ShardedDOTagCache implements NextModeTagCache {
111
98
  readonly defaultRegion: AllowedDurableObjectRegion;
112
99
  localCache?: Cache;
113
100
  constructor(opts?: ShardedDOTagCacheOptions);
114
- private getDurableObjectStub;
115
101
  /**
116
- * Generates a list of DO ids for the shards and replicas
117
- * @param tags The tags to generate shards for
118
- * @param shardType Whether to generate shards for soft or hard tags
119
- * @param generateAllShards Whether to generate all shards or only one
120
- * @returns An array of TagCacheDOId and tag
102
+ * Public API
121
103
  */
122
- private generateDOIdArray;
123
- getClosestRegion(): "enam" | "sam" | "weur" | "apac" | "oc" | "afr";
124
- /**
125
- * Same tags are guaranteed to be in the same shard
126
- * @param tags
127
- * @returns An array of DO ids and tags
128
- */
129
- groupTagsByDO({ tags, generateAllReplicas }: {
130
- tags: string[];
131
- generateAllReplicas?: boolean;
132
- }): {
133
- doId: DOId;
134
- tags: string[];
135
- }[];
136
- private getConfig;
137
104
  getLastRevalidated(tags: string[]): Promise<number>;
138
105
  /**
139
106
  * This function checks if the tags have been revalidated
@@ -150,9 +117,12 @@ declare class ShardedDOTagCache implements NextModeTagCache {
150
117
  * @returns
151
118
  */
152
119
  writeTags(tags: string[]): Promise<void>;
120
+ /**
121
+ * The following methods are public only because they are accessed from the tests
122
+ */
153
123
  performWriteTagsWithRetry(doId: DOId, tags: string[], lastModified: number, retryNumber?: number): Promise<void>;
154
- getCacheInstance(): Promise<Cache | undefined>;
155
124
  getCacheUrlKey(doId: DOId, tag: string): string;
125
+ getCacheInstance(): Promise<Cache | undefined>;
156
126
  /**
157
127
  * Get the last revalidation time for the tags from the regional cache
158
128
  * If the cache is not enabled, it will return an empty array
@@ -168,6 +138,42 @@ declare class ShardedDOTagCache implements NextModeTagCache {
168
138
  * This is used to ensure that the cache is cleared when the tags are revalidated
169
139
  */
170
140
  deleteRegionalCache(optsKey: CacheTagKeyOptions): Promise<void>;
141
+ /**
142
+ * Same tags are guaranteed to be in the same shard
143
+ * @param tags
144
+ * @returns An array of DO ids and tags
145
+ */
146
+ groupTagsByDO({ tags, generateAllReplicas, }: {
147
+ tags: string[];
148
+ generateAllReplicas?: boolean;
149
+ }): {
150
+ doId: DOId;
151
+ tags: string[];
152
+ }[];
153
+ private getDurableObjectStub;
154
+ /**
155
+ * Generates a list of DO ids for the shards and replicas
156
+ * @param tags The tags to generate shards for
157
+ * @param shardType Whether to generate shards for soft or hard tags
158
+ * @param generateAllShards Whether to generate all shards or only one
159
+ * @returns An array of TagCacheDOId and tag
160
+ */
161
+ private generateDOIdArray;
162
+ private getClosestRegion;
163
+ private getConfig;
164
+ }
165
+ export declare class DOId {
166
+ options: DOIdOptions;
167
+ shardId: string;
168
+ replicaId: number;
169
+ region?: DurableObjectLocationHint;
170
+ constructor(options: DOIdOptions);
171
+ private generateRandomNumberBetween;
172
+ get key(): string;
173
+ }
174
+ interface CacheTagKeyOptions {
175
+ doId: DOId;
176
+ tags: string[];
171
177
  }
172
178
  declare const _default: (opts?: ShardedDOTagCacheOptions) => ShardedDOTagCache;
173
179
  export default _default;
@@ -9,25 +9,6 @@ export const NAME = "do-sharded-tag-cache";
9
9
  const SOFT_TAG_PREFIX = "_N_T_/";
10
10
  export const DEFAULT_REGION = "enam";
11
11
  export const AVAILABLE_REGIONS = ["enam", "weur", "apac", "sam", "afr", "oc"];
12
- export class DOId {
13
- options;
14
- shardId;
15
- replicaId;
16
- region;
17
- constructor(options) {
18
- this.options = options;
19
- const { baseShardId, shardType, numberOfReplicas, replicaId, region } = options;
20
- this.shardId = `tag-${shardType};${baseShardId}`;
21
- this.replicaId = replicaId ?? this.generateRandomNumberBetween(1, numberOfReplicas);
22
- this.region = region;
23
- }
24
- generateRandomNumberBetween(min, max) {
25
- return Math.floor(Math.random() * (max - min + 1) + min);
26
- }
27
- get key() {
28
- return `${this.shardId};replica-${this.replicaId}${this.region ? `;region-${this.region}` : ""}`;
29
- }
30
- }
31
12
  class ShardedDOTagCache {
32
13
  opts;
33
14
  mode = "nextMode";
@@ -46,137 +27,11 @@ class ShardedDOTagCache {
46
27
  this.enableRegionalReplication = Boolean(opts.shardReplication?.regionalReplication);
47
28
  this.defaultRegion = opts.shardReplication?.regionalReplication?.defaultRegion ?? DEFAULT_REGION;
48
29
  }
49
- getDurableObjectStub(doId) {
50
- const durableObject = getCloudflareContext().env.NEXT_TAG_CACHE_DO_SHARDED;
51
- if (!durableObject)
52
- throw new IgnorableError("No durable object binding for cache revalidation");
53
- const id = durableObject.idFromName(doId.key);
54
- debug("[shardedTagCache] - Accessing Durable Object : ", {
55
- key: doId.key,
56
- region: doId.region,
57
- });
58
- return durableObject.get(id, { locationHint: doId.region });
59
- }
60
30
  /**
61
- * Generates a list of DO ids for the shards and replicas
62
- * @param tags The tags to generate shards for
63
- * @param shardType Whether to generate shards for soft or hard tags
64
- * @param generateAllShards Whether to generate all shards or only one
65
- * @returns An array of TagCacheDOId and tag
31
+ * Public API
66
32
  */
67
- generateDOIdArray({ tags, shardType, generateAllReplicas = false, }) {
68
- let replicaIndexes = [1];
69
- const isSoft = shardType === "soft";
70
- let numReplicas = 1;
71
- if (this.opts.shardReplication) {
72
- numReplicas = isSoft ? this.numSoftReplicas : this.numHardReplicas;
73
- replicaIndexes = generateAllReplicas
74
- ? Array.from({ length: numReplicas }, (_, i) => i + 1)
75
- : [undefined];
76
- }
77
- const regionalReplicas = replicaIndexes.flatMap((replicaId) => {
78
- return tags
79
- .filter((tag) => (isSoft ? tag.startsWith(SOFT_TAG_PREFIX) : !tag.startsWith(SOFT_TAG_PREFIX)))
80
- .map((tag) => {
81
- return {
82
- doId: new DOId({
83
- baseShardId: generateShardId(tag, this.opts.baseShardSize, "shard"),
84
- numberOfReplicas: numReplicas,
85
- shardType,
86
- replicaId,
87
- }),
88
- tag,
89
- };
90
- });
91
- });
92
- if (!this.enableRegionalReplication)
93
- return regionalReplicas;
94
- // If we have regional replication enabled, we need to further duplicate the shards in all the regions
95
- const regionalReplicasInAllRegions = generateAllReplicas
96
- ? regionalReplicas.flatMap(({ doId, tag }) => {
97
- return AVAILABLE_REGIONS.map((region) => {
98
- return {
99
- doId: new DOId({
100
- baseShardId: doId.options.baseShardId,
101
- numberOfReplicas: numReplicas,
102
- shardType,
103
- replicaId: doId.replicaId,
104
- region,
105
- }),
106
- tag,
107
- };
108
- });
109
- })
110
- : regionalReplicas.map(({ doId, tag }) => {
111
- doId.region = this.getClosestRegion();
112
- return { doId, tag };
113
- });
114
- return regionalReplicasInAllRegions;
115
- }
116
- getClosestRegion() {
117
- const continent = getCloudflareContext().cf?.continent;
118
- if (!continent)
119
- return this.defaultRegion;
120
- debug("[shardedTagCache] - Continent : ", continent);
121
- switch (continent) {
122
- case "AF":
123
- return "afr";
124
- case "AS":
125
- return "apac";
126
- case "EU":
127
- return "weur";
128
- case "NA":
129
- return "enam";
130
- case "OC":
131
- return "oc";
132
- case "SA":
133
- return "sam";
134
- default:
135
- return this.defaultRegion;
136
- }
137
- }
138
- /**
139
- * Same tags are guaranteed to be in the same shard
140
- * @param tags
141
- * @returns An array of DO ids and tags
142
- */
143
- groupTagsByDO({ tags, generateAllReplicas = false }) {
144
- // Here we'll start by splitting soft tags from hard tags
145
- // This will greatly increase the cache hit rate for the soft tag (which are the most likely to cause issue because of load)
146
- const softTags = this.generateDOIdArray({ tags, shardType: "soft", generateAllReplicas });
147
- const hardTags = this.generateDOIdArray({ tags, shardType: "hard", generateAllReplicas });
148
- const tagIdCollection = [...softTags, ...hardTags];
149
- // We then group the tags by DO id
150
- const tagsByDOId = new Map();
151
- for (const { doId, tag } of tagIdCollection) {
152
- const doIdString = doId.key;
153
- const tagsArray = tagsByDOId.get(doIdString)?.tags ?? [];
154
- tagsArray.push(tag);
155
- tagsByDOId.set(doIdString, {
156
- // We override the doId here, but it should be the same for all tags
157
- doId,
158
- tags: tagsArray,
159
- });
160
- }
161
- const result = Array.from(tagsByDOId.values());
162
- return result;
163
- }
164
- async getConfig() {
165
- const cfEnv = getCloudflareContext().env;
166
- const db = cfEnv.NEXT_TAG_CACHE_DO_SHARDED;
167
- if (!db)
168
- debugCache("No Durable object found");
169
- const isDisabled = !!globalThis.openNextConfig
170
- .dangerous?.disableTagCache;
171
- return !db || isDisabled
172
- ? { isDisabled: true }
173
- : {
174
- isDisabled: false,
175
- db,
176
- };
177
- }
178
33
  async getLastRevalidated(tags) {
179
- const { isDisabled } = await this.getConfig();
34
+ const { isDisabled } = this.getConfig();
180
35
  if (isDisabled)
181
36
  return 0;
182
37
  if (tags.length === 0)
@@ -214,7 +69,7 @@ class ShardedDOTagCache {
214
69
  * @returns
215
70
  */
216
71
  async hasBeenRevalidated(tags, lastModified) {
217
- const { isDisabled } = await this.getConfig();
72
+ const { isDisabled } = this.getConfig();
218
73
  if (isDisabled)
219
74
  return false;
220
75
  try {
@@ -251,7 +106,7 @@ class ShardedDOTagCache {
251
106
  * @returns
252
107
  */
253
108
  async writeTags(tags) {
254
- const { isDisabled } = await this.getConfig();
109
+ const { isDisabled } = this.getConfig();
255
110
  if (isDisabled)
256
111
  return;
257
112
  const shardedTagGroups = this.groupTagsByDO({ tags, generateAllReplicas: true });
@@ -262,6 +117,9 @@ class ShardedDOTagCache {
262
117
  }));
263
118
  await purgeCacheByTags(tags);
264
119
  }
120
+ /**
121
+ * The following methods are public only because they are accessed from the tests
122
+ */
265
123
  async performWriteTagsWithRetry(doId, tags, lastModified, retryNumber = 0) {
266
124
  try {
267
125
  const stub = this.getDurableObjectStub(doId);
@@ -285,16 +143,15 @@ class ShardedDOTagCache {
285
143
  await this.performWriteTagsWithRetry(doId, tags, lastModified, retryNumber + 1);
286
144
  }
287
145
  }
288
- // Cache API
146
+ getCacheUrlKey(doId, tag) {
147
+ return `http://local.cache/shard/${doId.shardId}?tag=${encodeURIComponent(tag)}`;
148
+ }
289
149
  async getCacheInstance() {
290
150
  if (!this.localCache && this.opts.regionalCache) {
291
151
  this.localCache = await caches.open("sharded-do-tag-cache");
292
152
  }
293
153
  return this.localCache;
294
154
  }
295
- getCacheUrlKey(doId, tag) {
296
- return `http://local.cache/shard/${doId.shardId}?tag=${encodeURIComponent(tag)}`;
297
- }
298
155
  /**
299
156
  * Get the last revalidation time for the tags from the regional cache
300
157
  * If the cache is not enabled, it will return an empty array
@@ -383,5 +240,154 @@ class ShardedDOTagCache {
383
240
  debugCache("Error while deleting from regional cache", e);
384
241
  }
385
242
  }
243
+ /**
244
+ * Same tags are guaranteed to be in the same shard
245
+ * @param tags
246
+ * @returns An array of DO ids and tags
247
+ */
248
+ groupTagsByDO({ tags, generateAllReplicas = false, }) {
249
+ // Here we'll start by splitting soft tags from hard tags
250
+ // This will greatly increase the cache hit rate for the soft tag (which are the most likely to cause issue because of load)
251
+ const softTags = this.generateDOIdArray({ tags, shardType: "soft", generateAllReplicas });
252
+ const hardTags = this.generateDOIdArray({ tags, shardType: "hard", generateAllReplicas });
253
+ const tagIdCollection = [...softTags, ...hardTags];
254
+ // We then group the tags by DO id
255
+ const tagsByDOId = new Map();
256
+ for (const { doId, tag } of tagIdCollection) {
257
+ const doIdString = doId.key;
258
+ const tagsArray = tagsByDOId.get(doIdString)?.tags ?? [];
259
+ tagsArray.push(tag);
260
+ tagsByDOId.set(doIdString, {
261
+ // We override the doId here, but it should be the same for all tags
262
+ doId,
263
+ tags: tagsArray,
264
+ });
265
+ }
266
+ const result = Array.from(tagsByDOId.values());
267
+ return result;
268
+ }
269
+ // Private methods
270
+ getDurableObjectStub(doId) {
271
+ const durableObject = getCloudflareContext().env.NEXT_TAG_CACHE_DO_SHARDED;
272
+ if (!durableObject)
273
+ throw new IgnorableError("No durable object binding for cache revalidation");
274
+ const id = durableObject.idFromName(doId.key);
275
+ debug("[shardedTagCache] - Accessing Durable Object : ", {
276
+ key: doId.key,
277
+ region: doId.region,
278
+ });
279
+ return durableObject.get(id, { locationHint: doId.region });
280
+ }
281
+ /**
282
+ * Generates a list of DO ids for the shards and replicas
283
+ * @param tags The tags to generate shards for
284
+ * @param shardType Whether to generate shards for soft or hard tags
285
+ * @param generateAllShards Whether to generate all shards or only one
286
+ * @returns An array of TagCacheDOId and tag
287
+ */
288
+ generateDOIdArray({ tags, shardType, generateAllReplicas = false, }) {
289
+ let replicaIndexes = [1];
290
+ const isSoft = shardType === "soft";
291
+ let numReplicas = 1;
292
+ if (this.opts.shardReplication) {
293
+ numReplicas = isSoft ? this.numSoftReplicas : this.numHardReplicas;
294
+ replicaIndexes = generateAllReplicas
295
+ ? Array.from({ length: numReplicas }, (_, i) => i + 1)
296
+ : [undefined];
297
+ }
298
+ const regionalReplicas = replicaIndexes.flatMap((replicaId) => {
299
+ return tags
300
+ .filter((tag) => (isSoft ? tag.startsWith(SOFT_TAG_PREFIX) : !tag.startsWith(SOFT_TAG_PREFIX)))
301
+ .map((tag) => {
302
+ return {
303
+ doId: new DOId({
304
+ baseShardId: generateShardId(tag, this.opts.baseShardSize, "shard"),
305
+ numberOfReplicas: numReplicas,
306
+ shardType,
307
+ replicaId,
308
+ }),
309
+ tag,
310
+ };
311
+ });
312
+ });
313
+ if (!this.enableRegionalReplication)
314
+ return regionalReplicas;
315
+ // If we have regional replication enabled, we need to further duplicate the shards in all the regions
316
+ const regionalReplicasInAllRegions = generateAllReplicas
317
+ ? regionalReplicas.flatMap(({ doId, tag }) => {
318
+ return AVAILABLE_REGIONS.map((region) => {
319
+ return {
320
+ doId: new DOId({
321
+ baseShardId: doId.options.baseShardId,
322
+ numberOfReplicas: numReplicas,
323
+ shardType,
324
+ replicaId: doId.replicaId,
325
+ region,
326
+ }),
327
+ tag,
328
+ };
329
+ });
330
+ })
331
+ : regionalReplicas.map(({ doId, tag }) => {
332
+ doId.region = this.getClosestRegion();
333
+ return { doId, tag };
334
+ });
335
+ return regionalReplicasInAllRegions;
336
+ }
337
+ getClosestRegion() {
338
+ const continent = getCloudflareContext().cf?.continent;
339
+ if (!continent)
340
+ return this.defaultRegion;
341
+ debug("[shardedTagCache] - Continent : ", continent);
342
+ switch (continent) {
343
+ case "AF":
344
+ return "afr";
345
+ case "AS":
346
+ return "apac";
347
+ case "EU":
348
+ return "weur";
349
+ case "NA":
350
+ return "enam";
351
+ case "OC":
352
+ return "oc";
353
+ case "SA":
354
+ return "sam";
355
+ default:
356
+ return this.defaultRegion;
357
+ }
358
+ }
359
+ getConfig() {
360
+ const cfEnv = getCloudflareContext().env;
361
+ const db = cfEnv.NEXT_TAG_CACHE_DO_SHARDED;
362
+ if (!db)
363
+ debugCache("No Durable object found");
364
+ const isDisabled = !!globalThis.openNextConfig
365
+ .dangerous?.disableTagCache;
366
+ return !db || isDisabled
367
+ ? { isDisabled: true }
368
+ : {
369
+ isDisabled: false,
370
+ db,
371
+ };
372
+ }
373
+ }
374
+ export class DOId {
375
+ options;
376
+ shardId;
377
+ replicaId;
378
+ region;
379
+ constructor(options) {
380
+ this.options = options;
381
+ const { baseShardId, shardType, numberOfReplicas, replicaId, region } = options;
382
+ this.shardId = `tag-${shardType};${baseShardId}`;
383
+ this.replicaId = replicaId ?? this.generateRandomNumberBetween(1, numberOfReplicas);
384
+ this.region = region;
385
+ }
386
+ generateRandomNumberBetween(min, max) {
387
+ return Math.floor(Math.random() * (max - min + 1) + min);
388
+ }
389
+ get key() {
390
+ return `${this.shardId};replica-${this.replicaId}${this.region ? `;region-${this.region}` : ""}`;
391
+ }
386
392
  }
387
393
  export default (opts) => new ShardedDOTagCache(opts);
@@ -6,7 +6,7 @@ import type { WithWranglerArgs } from "./utils.js";
6
6
  * @param args
7
7
  */
8
8
  export declare function deployCommand(args: WithWranglerArgs<{
9
- cacheChunkSize: number;
9
+ cacheChunkSize?: number;
10
10
  }>): Promise<void>;
11
11
  /**
12
12
  * Add the `deploy` command to yargs configuration.
@@ -24,6 +24,7 @@ export async function deployCommand(args) {
24
24
  environment: args.env,
25
25
  wranglerConfigPath: args.wranglerConfigPath,
26
26
  cacheChunkSize: args.cacheChunkSize,
27
+ shouldUsePreviewId: false,
27
28
  });
28
29
  runWrangler(options, [
29
30
  "deploy",
@@ -11,10 +11,28 @@ export type CacheAsset = {
11
11
  };
12
12
  export declare function getCacheAssets(opts: BuildOptions): CacheAsset[];
13
13
  type PopulateCacheOptions = {
14
+ /**
15
+ * Whether to populate the local or remote cache.
16
+ */
14
17
  target: WranglerTarget;
18
+ /**
19
+ * Wrangler environment to use.
20
+ */
15
21
  environment?: string;
22
+ /**
23
+ * Path to the Wrangler config file.
24
+ */
16
25
  wranglerConfigPath?: string;
26
+ /**
27
+ * Chunk sizes to use when populating KV cache. Ignored for R2.
28
+ *
29
+ * @default 25 for KV
30
+ */
17
31
  cacheChunkSize?: number;
32
+ /**
33
+ * Instructs Wrangler to use the preview namespace or ID defined in the Wrangler config for the remote target.
34
+ */
35
+ shouldUsePreviewId: boolean;
18
36
  };
19
37
  export declare function populateCache(options: BuildOptions, config: OpenNextConfig, wranglerConfig: WranglerConfig, populateCacheOptions: PopulateCacheOptions): Promise<void>;
20
38
  /**
@@ -30,6 +48,6 @@ export declare function withPopulateCacheOptions<T extends yargs.Argv>(args: T):
30
48
  } & {
31
49
  env: string | undefined;
32
50
  } & {
33
- cacheChunkSize: number;
51
+ cacheChunkSize: number | undefined;
34
52
  }>;
35
53
  export {};
@@ -110,7 +110,12 @@ async function populateKVIncrementalCache(options, config, populateCacheOptions)
110
110
  value: readFileSync(fullPath, "utf8"),
111
111
  }));
112
112
  writeFileSync(chunkPath, JSON.stringify(kvMapping));
113
- runWrangler(options, ["kv bulk put", quoteShellMeta(chunkPath), `--binding ${KV_CACHE_BINDING_NAME}`], {
113
+ runWrangler(options, [
114
+ "kv bulk put",
115
+ quoteShellMeta(chunkPath),
116
+ `--binding ${KV_CACHE_BINDING_NAME}`,
117
+ `--preview ${populateCacheOptions.shouldUsePreviewId}`,
118
+ ], {
114
119
  target: populateCacheOptions.target,
115
120
  environment: populateCacheOptions.environment,
116
121
  configPath: populateCacheOptions.wranglerConfigPath,
@@ -130,6 +135,7 @@ function populateD1TagCache(options, config, populateCacheOptions) {
130
135
  "d1 execute",
131
136
  D1_TAG_BINDING_NAME,
132
137
  `--command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);"`,
138
+ `--preview ${populateCacheOptions.shouldUsePreviewId}`,
133
139
  ], {
134
140
  target: populateCacheOptions.target,
135
141
  environment: populateCacheOptions.environment,
@@ -191,6 +197,7 @@ async function populateCacheCommand(target, args) {
191
197
  environment: args.env,
192
198
  wranglerConfigPath: args.wranglerConfigPath,
193
199
  cacheChunkSize: args.cacheChunkSize,
200
+ shouldUsePreviewId: false,
194
201
  });
195
202
  }
196
203
  /**
@@ -207,7 +214,6 @@ export function addPopulateCacheCommand(y) {
207
214
  export function withPopulateCacheOptions(args) {
208
215
  return withWranglerOptions(args).options("cacheChunkSize", {
209
216
  type: "number",
210
- default: 25,
211
217
  desc: "Number of entries per chunk when populating the cache",
212
218
  });
213
219
  }
@@ -6,7 +6,8 @@ import type { WithWranglerArgs } from "./utils.js";
6
6
  * @param args
7
7
  */
8
8
  export declare function previewCommand(args: WithWranglerArgs<{
9
- cacheChunkSize: number;
9
+ cacheChunkSize?: number;
10
+ remote: boolean;
10
11
  }>): Promise<void>;
11
12
  /**
12
13
  * Add the `preview` command to yargs configuration.
@@ -12,10 +12,11 @@ export async function previewCommand(args) {
12
12
  const options = getNormalizedOptions(config);
13
13
  const wranglerConfig = readWranglerConfig(args);
14
14
  await populateCache(options, config, wranglerConfig, {
15
- target: "local",
15
+ target: args.remote ? "remote" : "local",
16
16
  environment: args.env,
17
17
  wranglerConfigPath: args.wranglerConfigPath,
18
18
  cacheChunkSize: args.cacheChunkSize,
19
+ shouldUsePreviewId: args.remote,
19
20
  });
20
21
  runWrangler(options, ["dev", ...args.wranglerArgs], { logging: "all" });
21
22
  }
@@ -25,5 +26,10 @@ export async function previewCommand(args) {
25
26
  * Consumes 1 positional parameter.
26
27
  */
27
28
  export function addPreviewCommand(y) {
28
- return y.command("preview", "Preview a built OpenNext app with a Wrangler dev server", (c) => withPopulateCacheOptions(c), (args) => previewCommand(withWranglerPassthroughArgs(args)));
29
+ return y.command("preview", "Preview a built OpenNext app with a Wrangler dev server", (c) => withPopulateCacheOptions(c).option("remote", {
30
+ type: "boolean",
31
+ alias: "r",
32
+ default: false,
33
+ desc: "Run on the global Cloudflare network with access to production resources",
34
+ }), (args) => previewCommand(withWranglerPassthroughArgs(args)));
29
35
  }
@@ -6,7 +6,7 @@ import type { WithWranglerArgs } from "./utils.js";
6
6
  * @param args
7
7
  */
8
8
  export declare function uploadCommand(args: WithWranglerArgs<{
9
- cacheChunkSize: number;
9
+ cacheChunkSize?: number;
10
10
  }>): Promise<void>;
11
11
  /**
12
12
  * Add the `upload` command to yargs configuration.
@@ -24,6 +24,7 @@ export async function uploadCommand(args) {
24
24
  environment: args.env,
25
25
  wranglerConfigPath: args.wranglerConfigPath,
26
26
  cacheChunkSize: args.cacheChunkSize,
27
+ shouldUsePreviewId: false,
27
28
  });
28
29
  runWrangler(options, [
29
30
  "versions upload",
@@ -80,6 +80,7 @@ type WranglerInputArgs = {
80
80
  configPath: string | undefined;
81
81
  config: string | undefined;
82
82
  env: string | undefined;
83
+ remote?: boolean | undefined;
83
84
  };
84
85
  /**
85
86
  *
@@ -35,8 +35,7 @@ export async function compileConfig(configPath) {
35
35
  if (!configPath) {
36
36
  configPath = await createOpenNextConfigIfNotExistent(nextAppDir);
37
37
  }
38
- // TODO: remove the hack passing the `configPath` as the `baseDir` when https://github.com/opennextjs/opennextjs-aws/pull/972 is merged
39
- const { config, buildDir } = await compileOpenNextConfig(configPath, "", { compileEdge: true });
38
+ const { config, buildDir } = await compileOpenNextConfig(configPath, { compileEdge: true });
40
39
  ensureCloudflareConfig(config);
41
40
  return { config, buildDir };
42
41
  }
@@ -116,6 +115,7 @@ function getWranglerArgs(args) {
116
115
  ...(args.configPath ? ["--config", args.configPath] : []),
117
116
  ...(args.config ? ["--config", args.config] : []),
118
117
  ...(args.env ? ["--env", args.env] : []),
118
+ ...(args.remote ? ["--remote"] : []),
119
119
  // Note: the first args in `_` will be the commands.
120
120
  ...args._.slice(args._[0] === "populateCache" ? 2 : 1).map((a) => `${a}`),
121
121
  ];
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.8.2",
4
+ "version": "1.8.4",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -43,7 +43,7 @@
43
43
  "homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
44
44
  "dependencies": {
45
45
  "@dotenvx/dotenvx": "1.31.0",
46
- "@opennextjs/aws": "3.7.6",
46
+ "@opennextjs/aws": "3.7.7",
47
47
  "cloudflare": "^4.4.1",
48
48
  "enquirer": "^2.4.1",
49
49
  "glob": "^11.0.0",