@uniformdev/canvas-next-rsc 19.79.1-alpha.11 → 19.79.1-alpha.13

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.
@@ -61,4 +61,4 @@ type ResolveComponentsOptions = {
61
61
  mode: UniformCompositionProps['mode'];
62
62
  };
63
63
 
64
- export { ResolveComponentFunction as R, UniformCompositionProps as U, UniformComposition as a, ResolveComponentResult as b, resolveComposition as r };
64
+ export { type ResolveComponentFunction as R, type UniformCompositionProps as U, UniformComposition as a, type ResolveComponentResult as b, resolveComposition as r };
@@ -0,0 +1,64 @@
1
+ import * as React$1 from 'react';
2
+ import { ComponentType, ReactNode } from 'react';
3
+ import { ResolvedRouteGetResponse, ComponentInstance } from '@uniformdev/canvas';
4
+ import { PageParameters, ComponentProps, CompositionContext, AppDirectoryServerContext } from '@uniformdev/canvas-next-rsc-shared';
5
+
6
+ type UniformStaticCompositionProps = {
7
+ /**
8
+ * How to render the composition.
9
+ */
10
+ mode: 'static';
11
+ };
12
+ type UniformServerCompositionProps = {
13
+ /**
14
+ * How to render the composition.
15
+ */
16
+ mode: 'server';
17
+ /**
18
+ * The Context instance to use for server-side rendering.
19
+ */
20
+ serverContext?: AppDirectoryServerContext;
21
+ };
22
+ type UniformCompositionProps = PageParameters & {
23
+ /**
24
+ * The route data to render.
25
+ */
26
+ route: ResolvedRouteGetResponse | undefined;
27
+ /**
28
+ * Function to map composition components to React components.
29
+ */
30
+ resolveComponent: ResolveComponentFunction;
31
+ } & (UniformStaticCompositionProps | UniformServerCompositionProps);
32
+ declare const UniformComposition: React.FC<UniformCompositionProps>;
33
+ type ResolveComponentFunction = (options: {
34
+ component: ComponentInstance;
35
+ }) => ResolveComponentResult;
36
+ type ResolveComponentResult = {
37
+ component: ComponentType<ComponentProps<any, any>> | null;
38
+ includeContext?: boolean;
39
+ };
40
+ declare const resolveComposition: (props: Omit<ResolveComponentsOptions, 'slotName' | 'slotIndex' | 'target'> & {
41
+ composition: ComponentInstance;
42
+ compositionContext: CompositionContext;
43
+ }) => React$1.FunctionComponentElement<{
44
+ children?: ReactNode;
45
+ }> | null;
46
+ type ResolveComponentsOptions = {
47
+ serverContext?: AppDirectoryServerContext;
48
+ target: {
49
+ type: 'root';
50
+ composition: ComponentInstance;
51
+ } | {
52
+ type: 'slot';
53
+ components: ComponentInstance[];
54
+ parent: ComponentInstance;
55
+ root: ComponentInstance;
56
+ };
57
+ slotName: string | undefined;
58
+ slotIndex: number | undefined;
59
+ resolveComponent: ResolveComponentFunction;
60
+ compositionContext: CompositionContext;
61
+ mode: UniformCompositionProps['mode'];
62
+ };
63
+
64
+ export { type ResolveComponentFunction as R, type UniformCompositionProps as U, UniformComposition as a, type ResolveComponentResult as b, resolveComposition as r };
@@ -1,7 +1,7 @@
1
1
  import { ComponentProps, CompositionContext, SlotDefinition } from '@uniformdev/canvas-next-rsc-shared';
2
2
  export { ComponentProps, CompositionContext } from '@uniformdev/canvas-next-rsc-shared';
3
3
  import React__default, { PropsWithChildren, ReactNode, Key } from 'react';
4
- export { R as ResolveComponentFunction, b as ResolveComponentResult } from './UniformComposition-d178d865.js';
4
+ export { R as ResolveComponentFunction, b as ResolveComponentResult } from './UniformComposition-0pvEHduc.mjs';
5
5
  import { ComponentInstance } from '@uniformdev/canvas';
6
6
  import { RichTextNode } from '@uniformdev/richtext';
7
7
  import { PureUniformTextProps } from '@uniformdev/canvas-react/core';
@@ -59,6 +59,8 @@ type CustomSlotChildRenderFunc = (options: {
59
59
  child: ReactNode;
60
60
  component: ComponentInstance;
61
61
  key: Key;
62
+ slotName: string;
63
+ slotIndex: number;
62
64
  }) => JSX.Element;
63
65
  type UniformSlotProps = {
64
66
  data: ComponentInstance;
@@ -73,4 +75,4 @@ type UniformTextProps = {
73
75
  } & Omit<PureUniformTextProps, 'skipCustomRendering' | 'isContextualEditing'>;
74
76
  declare const UniformText: ({ context, ...rest }: UniformTextProps) => React__default.JSX.Element;
75
77
 
76
- export { CustomSlotChildRenderFunc, DefaultNotImplementedComponent, UniformRichText, UniformRichTextProps, UniformSlot, UniformSlotProps, UniformText, UniformTextProps };
78
+ export { type CustomSlotChildRenderFunc, DefaultNotImplementedComponent, UniformRichText, type UniformRichTextProps, UniformSlot, type UniformSlotProps, UniformText, type UniformTextProps };
@@ -1,7 +1,7 @@
1
1
  import { ComponentProps, CompositionContext, SlotDefinition } from '@uniformdev/canvas-next-rsc-shared';
2
2
  export { ComponentProps, CompositionContext } from '@uniformdev/canvas-next-rsc-shared';
3
3
  import React__default, { PropsWithChildren, ReactNode, Key } from 'react';
4
- export { R as ResolveComponentFunction, b as ResolveComponentResult } from './UniformComposition-d178d865.js';
4
+ export { R as ResolveComponentFunction, b as ResolveComponentResult } from './UniformComposition-0pvEHduc.js';
5
5
  import { ComponentInstance } from '@uniformdev/canvas';
6
6
  import { RichTextNode } from '@uniformdev/richtext';
7
7
  import { PureUniformTextProps } from '@uniformdev/canvas-react/core';
@@ -59,6 +59,8 @@ type CustomSlotChildRenderFunc = (options: {
59
59
  child: ReactNode;
60
60
  component: ComponentInstance;
61
61
  key: Key;
62
+ slotName: string;
63
+ slotIndex: number;
62
64
  }) => JSX.Element;
63
65
  type UniformSlotProps = {
64
66
  data: ComponentInstance;
@@ -73,4 +75,4 @@ type UniformTextProps = {
73
75
  } & Omit<PureUniformTextProps, 'skipCustomRendering' | 'isContextualEditing'>;
74
76
  declare const UniformText: ({ context, ...rest }: UniformTextProps) => React__default.JSX.Element;
75
77
 
76
- export { CustomSlotChildRenderFunc, DefaultNotImplementedComponent, UniformRichText, UniformRichTextProps, UniformSlot, UniformSlotProps, UniformText, UniformTextProps };
78
+ export { type CustomSlotChildRenderFunc, DefaultNotImplementedComponent, UniformRichText, type UniformRichTextProps, UniformSlot, type UniformSlotProps, UniformText, type UniformTextProps };
package/dist/component.js CHANGED
@@ -181,7 +181,9 @@ var UniformSlot = ({ data, slot, children }) => {
181
181
  const result = children({
182
182
  child,
183
183
  component: targetSlotData[i],
184
- key: `inner-${i}`
184
+ key: `inner-${i}`,
185
+ slotName: slot.name,
186
+ slotIndex: i
185
187
  });
186
188
  resolved.push(result);
187
189
  }
@@ -142,7 +142,9 @@ var UniformSlot = ({ data, slot, children }) => {
142
142
  const result = children({
143
143
  child,
144
144
  component: targetSlotData[i],
145
- key: `inner-${i}`
145
+ key: `inner-${i}`,
146
+ slotName: slot.name,
147
+ slotIndex: i
146
148
  });
147
149
  resolved.push(result);
148
150
  }
@@ -7,6 +7,6 @@ declare const createPreviewGETRouteHandler: (options?: CreatePreviewGETRouteHand
7
7
 
8
8
  declare const createPreviewOPTIONSRouteHandler: () => () => Promise<Response>;
9
9
 
10
- declare const createPreviewPOSTRouteHandler: () => (request: Request) => Promise<Response>;
10
+ declare const createPreviewPOSTRouteHandler: () => (request: NextRequest) => Promise<Response>;
11
11
 
12
- export { CreatePreviewGETRouteHandlerOptions, createPreviewGETRouteHandler, createPreviewOPTIONSRouteHandler, createPreviewPOSTRouteHandler };
12
+ export { type CreatePreviewGETRouteHandlerOptions, createPreviewGETRouteHandler, createPreviewOPTIONSRouteHandler, createPreviewPOSTRouteHandler };
package/dist/handler.d.ts CHANGED
@@ -7,6 +7,6 @@ declare const createPreviewGETRouteHandler: (options?: CreatePreviewGETRouteHand
7
7
 
8
8
  declare const createPreviewOPTIONSRouteHandler: () => () => Promise<Response>;
9
9
 
10
- declare const createPreviewPOSTRouteHandler: () => (request: Request) => Promise<Response>;
10
+ declare const createPreviewPOSTRouteHandler: () => (request: NextRequest) => Promise<Response>;
11
11
 
12
- export { CreatePreviewGETRouteHandlerOptions, createPreviewGETRouteHandler, createPreviewOPTIONSRouteHandler, createPreviewPOSTRouteHandler };
12
+ export { type CreatePreviewGETRouteHandlerOptions, createPreviewGETRouteHandler, createPreviewOPTIONSRouteHandler, createPreviewPOSTRouteHandler };
package/dist/handler.js CHANGED
@@ -27,15 +27,18 @@ __export(handler_exports, {
27
27
  module.exports = __toCommonJS(handler_exports);
28
28
 
29
29
  // src/handler/createPreviewGETRouteHandler.ts
30
- var import_canvas4 = require("@uniformdev/canvas");
30
+ var import_canvas5 = require("@uniformdev/canvas");
31
31
  var import_headers2 = require("next/headers");
32
32
  var import_navigation = require("next/navigation");
33
33
 
34
34
  // src/utils/route.ts
35
- var import_canvas3 = require("@uniformdev/canvas");
35
+ var import_canvas4 = require("@uniformdev/canvas");
36
36
  var import_canvas_next_rsc_shared2 = require("@uniformdev/canvas-next-rsc-shared");
37
37
  var import_redirect = require("@uniformdev/redirect");
38
38
 
39
+ // src/clients/canvasClient.ts
40
+ var import_canvas2 = require("@uniformdev/canvas");
41
+
39
42
  // src/config/helpers.ts
40
43
  var import_canvas_next_rsc_shared = require("@uniformdev/canvas-next-rsc-shared");
41
44
 
@@ -145,10 +148,58 @@ var determineFetchCacheOptions = (mode) => {
145
148
  };
146
149
  };
147
150
 
151
+ // src/clients/canvasClient.ts
152
+ var getCanvasClient = (options) => {
153
+ return new import_canvas2.CanvasClient({
154
+ projectId: env.getProjectId(),
155
+ apiHost: env.getApiHost(),
156
+ apiKey: env.getApiKey(),
157
+ edgeApiHost: env.getEdgeApiHost(),
158
+ fetch: (req, init) => {
159
+ let requestedUrl;
160
+ if (typeof req === "string") {
161
+ requestedUrl = new URL(req);
162
+ } else if (req instanceof URL) {
163
+ requestedUrl = req;
164
+ } else {
165
+ requestedUrl = new URL(req.url);
166
+ }
167
+ const tags = [];
168
+ if (requestedUrl) {
169
+ const compositionIdKey = "compositionId";
170
+ const compositionIdsKey = "compositionIDs";
171
+ const compositionId = requestedUrl.searchParams.get(compositionIdKey);
172
+ const compositionIds = requestedUrl.searchParams.get(compositionIdsKey);
173
+ if (compositionId) {
174
+ tags.push(buildCompositionTag(compositionId));
175
+ }
176
+ if (compositionIds) {
177
+ const ids = compositionIds.split(",");
178
+ for (let i = 0; i < ids.length; i++) {
179
+ tags.push(buildCompositionTag(ids[i]));
180
+ }
181
+ }
182
+ }
183
+ const { cache, revalidate } = determineFetchCacheOptions(options.cache);
184
+ return fetch(req, {
185
+ ...init,
186
+ cache,
187
+ headers: {
188
+ ...init == null ? void 0 : init.headers,
189
+ "x-bypass-cache": "true"
190
+ },
191
+ next: {
192
+ revalidate
193
+ }
194
+ });
195
+ }
196
+ });
197
+ };
198
+
148
199
  // src/clients/routeClient.ts
149
- var import_canvas2 = require("@uniformdev/canvas");
200
+ var import_canvas3 = require("@uniformdev/canvas");
150
201
  var getRouteClient = (options) => {
151
- const client = new import_canvas2.RouteClient({
202
+ const client = new import_canvas3.RouteClient({
152
203
  projectId: env.getProjectId(),
153
204
  apiKey: env.getApiKey(),
154
205
  edgeApiHost: env.getEdgeApiHost(),
@@ -161,7 +212,7 @@ var getRouteClient = (options) => {
161
212
  } else {
162
213
  requestedUrl = new URL(req.url);
163
214
  }
164
- const tags = [];
215
+ const tags = ["route"];
165
216
  if (requestedUrl) {
166
217
  const pathKey = "path";
167
218
  const path = requestedUrl.searchParams.get(pathKey);
@@ -203,30 +254,39 @@ var getDefaultRouteClient = ({ searchParams }) => {
203
254
  var retrieveRouteByPath = async ({
204
255
  path,
205
256
  state,
206
- searchParams
257
+ searchParams,
258
+ fetchOptions
207
259
  }) => {
208
260
  var _a;
209
261
  const client = getDefaultRouteClient({
210
262
  searchParams
211
263
  });
264
+ let queryPath = path;
265
+ if (searchParams && Object.keys(searchParams).length > 0) {
266
+ const helper = new URL((0, import_canvas_next_rsc_shared2.getBaseUrl)());
267
+ helper.pathname = path;
268
+ Object.entries(searchParams).forEach(([key, value]) => {
269
+ if (typeof value === "string") {
270
+ helper.searchParams.set(key, value);
271
+ }
272
+ });
273
+ if (helper.searchParams.size > 0) {
274
+ queryPath = `${helper.pathname}${helper.search}`;
275
+ }
276
+ }
212
277
  return await client.getRoute({
213
- path,
278
+ ...fetchOptions,
279
+ path: queryPath,
214
280
  state,
215
281
  withComponentIDs: true,
216
282
  withContentSourceMap: isOnVercelPreviewEnvironment() && ((_a = (0, import_canvas_next_rsc_shared2.getServerConfig)().experimental) == null ? void 0 : _a.vercelVisualEditing)
217
283
  });
218
284
  };
219
285
  var resolveRedirectHref = (resolveResult, path) => {
220
- let href;
221
- if (resolveResult.redirect.targetProjectMapNodeId) {
222
- const requestUrl = `${(0, import_canvas_next_rsc_shared2.getBaseUrl)()}${path}`;
223
- const expandedUrl = (0, import_redirect.getTargetVariableExpandedUrl)(requestUrl, resolveResult.redirect);
224
- const url = new URL(expandedUrl);
225
- href = url.pathname;
226
- } else {
227
- href = resolveResult.redirect.targetUrl;
228
- }
229
- return href;
286
+ const requestUrl = `${(0, import_canvas_next_rsc_shared2.getBaseUrl)()}${path}`;
287
+ const expandedUrl = (0, import_redirect.getTargetVariableExpandedUrl)(requestUrl, resolveResult.redirect);
288
+ const url = new URL(expandedUrl);
289
+ return url.pathname;
230
290
  };
231
291
 
232
292
  // src/handler/createPreviewGETRouteHandler.ts
@@ -262,7 +322,7 @@ var createPreviewGETRouteHandler = (options) => {
262
322
  const { searchParams } = new URL(request.url);
263
323
  const secret = searchParams.get("secret");
264
324
  const path = searchParams.get("path");
265
- const isPlayground = searchParams.get(import_canvas4.IN_CONTEXT_EDITOR_PLAYGROUND_QUERY_STRING_PARAM) === "true";
325
+ const isPlayground = searchParams.get(import_canvas5.IN_CONTEXT_EDITOR_PLAYGROUND_QUERY_STRING_PARAM) === "true";
266
326
  const id = searchParams.get("id");
267
327
  if (secret !== process.env.UNIFORM_PREVIEW_SECRET) {
268
328
  return new Response("Invalid preview secret", { status: 401 });
@@ -273,17 +333,17 @@ var createPreviewGETRouteHandler = (options) => {
273
333
  }
274
334
  const resolveResult = await retrieveRouteByPath({
275
335
  path,
276
- state: import_canvas4.CANVAS_DRAFT_STATE,
336
+ state: import_canvas5.CANVAS_DRAFT_STATE,
277
337
  searchParams: {
278
338
  // about to be in draft mode so pretend for now.
279
- [import_canvas4.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM]: "true"
339
+ [import_canvas5.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM]: "true"
280
340
  }
281
341
  });
282
342
  (0, import_headers2.draftMode)().enable();
283
343
  if (resolveResult.type === "redirect") {
284
344
  const href = resolveRedirectHref(resolveResult, path);
285
345
  if (resolveResult.redirect.targetProjectMapNodeId) {
286
- (0, import_navigation.redirect)(`${href}?${import_canvas4.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
346
+ (0, import_navigation.redirect)(`${href}?${import_canvas5.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
287
347
  } else {
288
348
  (0, import_navigation.redirect)(href);
289
349
  }
@@ -291,13 +351,13 @@ var createPreviewGETRouteHandler = (options) => {
291
351
  if (resolveResult.type === "notFound") {
292
352
  return new Response("Invalid path", { status: 401 });
293
353
  }
294
- (0, import_navigation.redirect)(`${path}?${import_canvas4.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
354
+ (0, import_navigation.redirect)(`${path}?${import_canvas5.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
295
355
  } else {
296
356
  if (!(options == null ? void 0 : options.playgroundPath)) {
297
357
  return new Response("No playground path is configured", { status: 401 });
298
358
  }
299
359
  (0, import_headers2.draftMode)().enable();
300
- (0, import_navigation.redirect)(`${options.playgroundPath}?id=${id}&${import_canvas4.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
360
+ (0, import_navigation.redirect)(`${options.playgroundPath}?id=${id}&${import_canvas5.IN_CONTEXT_EDITOR_QUERY_STRING_PARAM}=true`);
301
361
  }
302
362
  };
303
363
  };
@@ -316,9 +376,11 @@ var createPreviewOPTIONSRouteHandler = () => {
316
376
  };
317
377
 
318
378
  // src/handler/createPreviewPOSTRouteHandler.ts
379
+ var import_canvas7 = require("@uniformdev/canvas");
319
380
  var import_cache = require("next/cache");
320
381
 
321
382
  // src/handler/helpers.ts
383
+ var import_canvas6 = require("@uniformdev/canvas");
322
384
  var import_canvas_next_rsc_shared3 = require("@uniformdev/canvas-next-rsc-shared");
323
385
  var import_edge_config = require("@vercel/edge-config");
324
386
  var import_svix = require("svix");
@@ -382,10 +444,16 @@ var processCompositionChange = async (compositionId) => {
382
444
  type: "no-cache"
383
445
  }
384
446
  });
385
- const { nodes } = await projectMapClient.getNodes({
386
- compositionId
387
- });
447
+ const [{ nodes }, composition] = await Promise.all([
448
+ projectMapClient.getNodes({
449
+ compositionId
450
+ }),
451
+ getComposition({ compositionId })
452
+ ]);
388
453
  const tags = [];
454
+ if (composition == null ? void 0 : composition.pattern) {
455
+ tags.push("route");
456
+ }
389
457
  if (nodes) {
390
458
  for (let i = 0; i < nodes.length; i++) {
391
459
  const node = nodes[i];
@@ -400,6 +468,24 @@ var processCompositionChange = async (compositionId) => {
400
468
  tags
401
469
  };
402
470
  };
471
+ var getComposition = async ({ compositionId }) => {
472
+ const canvasClient = getCanvasClient({
473
+ cache: {
474
+ type: "no-cache"
475
+ }
476
+ });
477
+ try {
478
+ const composition = await canvasClient.getCompositionById({
479
+ compositionId
480
+ });
481
+ return composition;
482
+ } catch (err) {
483
+ if (err instanceof import_canvas6.ApiClientError && err.statusCode === 404) {
484
+ return null;
485
+ }
486
+ throw err;
487
+ }
488
+ };
403
489
  var buildProjectMapNodePaths = (path) => {
404
490
  const tags = [];
405
491
  const isDynamic = path.includes(":");
@@ -649,6 +735,25 @@ var handleRedirectUpdate = async (body) => {
649
735
  // src/handler/createPreviewPOSTRouteHandler.ts
650
736
  var createPreviewPOSTRouteHandler = () => {
651
737
  return async (request) => {
738
+ let previewSecretPassed = false;
739
+ if (process.env.UNIFORM_PREVIEW_SECRET) {
740
+ const secretValue = request.nextUrl.searchParams.get(import_canvas7.SECRET_QUERY_STRING_PARAM);
741
+ if (secretValue !== process.env.UNIFORM_PREVIEW_SECRET) {
742
+ console.warn(
743
+ "The preview secret passed in the query string does not match the UNIFORM_PREVIEW_SECRET env var."
744
+ );
745
+ } else {
746
+ previewSecretPassed = true;
747
+ }
748
+ } else {
749
+ if (!process.env.UNIFORM_WEBHOOK_SECRET) {
750
+ console.warn("Both UNIFORM_PREVIEW_SECRET and UNIFORM_WEBHOOK_SECRET are not set.");
751
+ }
752
+ previewSecretPassed = true;
753
+ }
754
+ if (!previewSecretPassed) {
755
+ return new Response("The request could not be validated.", { status: 401 });
756
+ }
652
757
  const { looksLikeMessage, validation } = await isSvixMessage(request);
653
758
  if (looksLikeMessage) {
654
759
  if (!validation) {
@@ -673,7 +778,13 @@ var handleSvixMessage = async (request) => {
673
778
  handleManifestPublished
674
779
  ];
675
780
  let tags = void 0;
676
- const jsonBody = await request.json();
781
+ let jsonBody;
782
+ try {
783
+ jsonBody = await request.json();
784
+ } catch (err) {
785
+ console.error("Error parsing the request body as JSON.", err);
786
+ return new Response("Error parsing the request body as JSON.", { status: 400 });
787
+ }
677
788
  for (let i = 0; i < handlers.length; i++) {
678
789
  const handler = handlers[i];
679
790
  const result = await handler(jsonBody);
package/dist/handler.mjs CHANGED
@@ -16,6 +16,9 @@ import {
16
16
  import { getBaseUrl, getServerConfig as getServerConfig2, resolvePath } from "@uniformdev/canvas-next-rsc-shared";
17
17
  import { getTargetVariableExpandedUrl } from "@uniformdev/redirect";
18
18
 
19
+ // src/clients/canvasClient.ts
20
+ import { CanvasClient } from "@uniformdev/canvas";
21
+
19
22
  // src/config/helpers.ts
20
23
  import { getServerConfig } from "@uniformdev/canvas-next-rsc-shared";
21
24
 
@@ -125,6 +128,54 @@ var determineFetchCacheOptions = (mode) => {
125
128
  };
126
129
  };
127
130
 
131
+ // src/clients/canvasClient.ts
132
+ var getCanvasClient = (options) => {
133
+ return new CanvasClient({
134
+ projectId: env.getProjectId(),
135
+ apiHost: env.getApiHost(),
136
+ apiKey: env.getApiKey(),
137
+ edgeApiHost: env.getEdgeApiHost(),
138
+ fetch: (req, init) => {
139
+ let requestedUrl;
140
+ if (typeof req === "string") {
141
+ requestedUrl = new URL(req);
142
+ } else if (req instanceof URL) {
143
+ requestedUrl = req;
144
+ } else {
145
+ requestedUrl = new URL(req.url);
146
+ }
147
+ const tags = [];
148
+ if (requestedUrl) {
149
+ const compositionIdKey = "compositionId";
150
+ const compositionIdsKey = "compositionIDs";
151
+ const compositionId = requestedUrl.searchParams.get(compositionIdKey);
152
+ const compositionIds = requestedUrl.searchParams.get(compositionIdsKey);
153
+ if (compositionId) {
154
+ tags.push(buildCompositionTag(compositionId));
155
+ }
156
+ if (compositionIds) {
157
+ const ids = compositionIds.split(",");
158
+ for (let i = 0; i < ids.length; i++) {
159
+ tags.push(buildCompositionTag(ids[i]));
160
+ }
161
+ }
162
+ }
163
+ const { cache, revalidate } = determineFetchCacheOptions(options.cache);
164
+ return fetch(req, {
165
+ ...init,
166
+ cache,
167
+ headers: {
168
+ ...init == null ? void 0 : init.headers,
169
+ "x-bypass-cache": "true"
170
+ },
171
+ next: {
172
+ revalidate
173
+ }
174
+ });
175
+ }
176
+ });
177
+ };
178
+
128
179
  // src/clients/routeClient.ts
129
180
  import { RouteClient } from "@uniformdev/canvas";
130
181
  var getRouteClient = (options) => {
@@ -141,7 +192,7 @@ var getRouteClient = (options) => {
141
192
  } else {
142
193
  requestedUrl = new URL(req.url);
143
194
  }
144
- const tags = [];
195
+ const tags = ["route"];
145
196
  if (requestedUrl) {
146
197
  const pathKey = "path";
147
198
  const path = requestedUrl.searchParams.get(pathKey);
@@ -183,30 +234,39 @@ var getDefaultRouteClient = ({ searchParams }) => {
183
234
  var retrieveRouteByPath = async ({
184
235
  path,
185
236
  state,
186
- searchParams
237
+ searchParams,
238
+ fetchOptions
187
239
  }) => {
188
240
  var _a;
189
241
  const client = getDefaultRouteClient({
190
242
  searchParams
191
243
  });
244
+ let queryPath = path;
245
+ if (searchParams && Object.keys(searchParams).length > 0) {
246
+ const helper = new URL(getBaseUrl());
247
+ helper.pathname = path;
248
+ Object.entries(searchParams).forEach(([key, value]) => {
249
+ if (typeof value === "string") {
250
+ helper.searchParams.set(key, value);
251
+ }
252
+ });
253
+ if (helper.searchParams.size > 0) {
254
+ queryPath = `${helper.pathname}${helper.search}`;
255
+ }
256
+ }
192
257
  return await client.getRoute({
193
- path,
258
+ ...fetchOptions,
259
+ path: queryPath,
194
260
  state,
195
261
  withComponentIDs: true,
196
262
  withContentSourceMap: isOnVercelPreviewEnvironment() && ((_a = getServerConfig2().experimental) == null ? void 0 : _a.vercelVisualEditing)
197
263
  });
198
264
  };
199
265
  var resolveRedirectHref = (resolveResult, path) => {
200
- let href;
201
- if (resolveResult.redirect.targetProjectMapNodeId) {
202
- const requestUrl = `${getBaseUrl()}${path}`;
203
- const expandedUrl = getTargetVariableExpandedUrl(requestUrl, resolveResult.redirect);
204
- const url = new URL(expandedUrl);
205
- href = url.pathname;
206
- } else {
207
- href = resolveResult.redirect.targetUrl;
208
- }
209
- return href;
266
+ const requestUrl = `${getBaseUrl()}${path}`;
267
+ const expandedUrl = getTargetVariableExpandedUrl(requestUrl, resolveResult.redirect);
268
+ const url = new URL(expandedUrl);
269
+ return url.pathname;
210
270
  };
211
271
 
212
272
  // src/handler/createPreviewGETRouteHandler.ts
@@ -296,9 +356,11 @@ var createPreviewOPTIONSRouteHandler = () => {
296
356
  };
297
357
 
298
358
  // src/handler/createPreviewPOSTRouteHandler.ts
359
+ import { SECRET_QUERY_STRING_PARAM } from "@uniformdev/canvas";
299
360
  import { revalidateTag } from "next/cache";
300
361
 
301
362
  // src/handler/helpers.ts
363
+ import { ApiClientError } from "@uniformdev/canvas";
302
364
  import { getServerConfig as getServerConfig3 } from "@uniformdev/canvas-next-rsc-shared";
303
365
  import { parseConnectionString } from "@vercel/edge-config";
304
366
  import { Webhook } from "svix";
@@ -362,10 +424,16 @@ var processCompositionChange = async (compositionId) => {
362
424
  type: "no-cache"
363
425
  }
364
426
  });
365
- const { nodes } = await projectMapClient.getNodes({
366
- compositionId
367
- });
427
+ const [{ nodes }, composition] = await Promise.all([
428
+ projectMapClient.getNodes({
429
+ compositionId
430
+ }),
431
+ getComposition({ compositionId })
432
+ ]);
368
433
  const tags = [];
434
+ if (composition == null ? void 0 : composition.pattern) {
435
+ tags.push("route");
436
+ }
369
437
  if (nodes) {
370
438
  for (let i = 0; i < nodes.length; i++) {
371
439
  const node = nodes[i];
@@ -380,6 +448,24 @@ var processCompositionChange = async (compositionId) => {
380
448
  tags
381
449
  };
382
450
  };
451
+ var getComposition = async ({ compositionId }) => {
452
+ const canvasClient = getCanvasClient({
453
+ cache: {
454
+ type: "no-cache"
455
+ }
456
+ });
457
+ try {
458
+ const composition = await canvasClient.getCompositionById({
459
+ compositionId
460
+ });
461
+ return composition;
462
+ } catch (err) {
463
+ if (err instanceof ApiClientError && err.statusCode === 404) {
464
+ return null;
465
+ }
466
+ throw err;
467
+ }
468
+ };
383
469
  var buildProjectMapNodePaths = (path) => {
384
470
  const tags = [];
385
471
  const isDynamic = path.includes(":");
@@ -629,6 +715,25 @@ var handleRedirectUpdate = async (body) => {
629
715
  // src/handler/createPreviewPOSTRouteHandler.ts
630
716
  var createPreviewPOSTRouteHandler = () => {
631
717
  return async (request) => {
718
+ let previewSecretPassed = false;
719
+ if (process.env.UNIFORM_PREVIEW_SECRET) {
720
+ const secretValue = request.nextUrl.searchParams.get(SECRET_QUERY_STRING_PARAM);
721
+ if (secretValue !== process.env.UNIFORM_PREVIEW_SECRET) {
722
+ console.warn(
723
+ "The preview secret passed in the query string does not match the UNIFORM_PREVIEW_SECRET env var."
724
+ );
725
+ } else {
726
+ previewSecretPassed = true;
727
+ }
728
+ } else {
729
+ if (!process.env.UNIFORM_WEBHOOK_SECRET) {
730
+ console.warn("Both UNIFORM_PREVIEW_SECRET and UNIFORM_WEBHOOK_SECRET are not set.");
731
+ }
732
+ previewSecretPassed = true;
733
+ }
734
+ if (!previewSecretPassed) {
735
+ return new Response("The request could not be validated.", { status: 401 });
736
+ }
632
737
  const { looksLikeMessage, validation } = await isSvixMessage(request);
633
738
  if (looksLikeMessage) {
634
739
  if (!validation) {
@@ -653,7 +758,13 @@ var handleSvixMessage = async (request) => {
653
758
  handleManifestPublished
654
759
  ];
655
760
  let tags = void 0;
656
- const jsonBody = await request.json();
761
+ let jsonBody;
762
+ try {
763
+ jsonBody = await request.json();
764
+ } catch (err) {
765
+ console.error("Error parsing the request body as JSON.", err);
766
+ return new Response("Error parsing the request body as JSON.", { status: 400 });
767
+ }
657
768
  for (let i = 0; i < handlers.length; i++) {
658
769
  const handler = handlers[i];
659
770
  const result = await handler(jsonBody);