camox 0.42.0 → 0.44.0
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/bin/camox.mjs +9 -1
- package/dist/core/components/lexical/{GradientNode.js → HighlightNode.js} +34 -34
- package/dist/core/components/lexical/InlineLexicalEditor.js +14 -14
- package/dist/core/components/lexical/InlineStylesPlugin.js +25 -9
- package/dist/core/components/lexical/SelectionBroadcaster.js +7 -7
- package/dist/core/components/lexical/SidebarLexicalEditor.js +24 -24
- package/dist/core/components/lexical/TextLinkPopover.js +191 -208
- package/dist/core/components/lexical/editorConfig.js +2 -2
- package/dist/core/createApp.d.ts +31 -4
- package/dist/core/createApp.js +2 -1
- package/dist/core/createBlock.js +24 -10
- package/dist/core/createLayout.d.ts +16 -3
- package/dist/core/createLayout.js +15 -15
- package/dist/core/derivedRoutes.js +1 -1
- package/dist/core/dom.d.ts +17 -0
- package/dist/core/dom.js +22 -0
- package/dist/core/editing/createEditableBlock.d.ts +135 -1
- package/dist/core/editing/createEditableBlock.js +209 -74
- package/dist/core/lib/contentType.d.ts +5 -0
- package/dist/core/lib/contentType.js +11 -0
- package/dist/core/lib/fieldTypes.js +1 -0
- package/dist/core/lib/iconTypes.d.ts +13 -0
- package/dist/core/lib/icons.d.ts +6 -0
- package/dist/core/lib/icons.js +130 -0
- package/dist/core/lib/lexicalReact.js +4 -4
- package/dist/core/lib/lexicalState.js +8 -8
- package/dist/core/lib/modifierFormats.js +2 -2
- package/dist/core/lib/textLinks.js +5 -2
- package/dist/core/lib/textStyles.d.ts +3 -3
- package/dist/core/lib/textStyles.js +9 -14
- package/dist/core/pageDestinations.js +37 -0
- package/dist/features/content/components/AssetCard.js +104 -68
- package/dist/features/og/imageResponse.node.js +11 -9
- package/dist/features/preview/CamoxPreview.js +148 -146
- package/dist/features/preview/commentsEnabled.js +2 -2
- package/dist/features/preview/components/AddBlockSidebar.js +1 -1
- package/dist/features/preview/components/AssetLightbox.js +17 -6
- package/dist/features/preview/components/AttachedComments.js +224 -87
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/CommentTargetQuote.js +22 -21
- package/dist/features/preview/components/CreatePageModal.js +4 -4
- package/dist/features/preview/components/DerivedLayoutDialog.js +36 -21
- package/dist/features/preview/components/DerivedLayoutSidebar.js +45 -26
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +38 -26
- package/dist/features/preview/components/FieldOverlayStyles.js +29 -9
- package/dist/features/preview/components/FieldToolbar.js +12 -12
- package/dist/features/preview/components/IconFieldEditor.js +231 -0
- package/dist/features/preview/components/ItemFieldsEditor.js +21 -14
- package/dist/features/preview/components/LinkFieldEditor.js +212 -209
- package/dist/features/preview/components/OverlayTracker.js +1 -1
- package/dist/features/preview/components/PageEditorSidebar.js +1 -1
- package/dist/features/preview/components/PageInfoSidebar.js +28 -28
- package/dist/features/preview/components/PagePicker.js +46 -46
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +224 -225
- package/dist/features/preview/components/PublicationRow.js +8 -4
- package/dist/features/preview/components/SendFeedbackDialog.js +83 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +1 -1
- package/dist/features/preview/overlayHighlights.js +54 -0
- package/dist/features/preview/previewCommentsStore.js +54 -34
- package/dist/features/preview/previewSelection.js +28 -23
- package/dist/features/preview/publication.js +10 -0
- package/dist/features/preview/usePageComments.js +39 -0
- package/dist/features/provider/CoreCamoxProvider.js +38 -6
- package/dist/features/provider/LocalhostPreviewProvider.js +81 -45
- package/dist/features/provider/components/CommandPalette.js +35 -84
- package/dist/features/runtime/pageApp.js +32 -28
- package/dist/features/runtime/pageServer.js +4 -1
- package/dist/features/runtime/runtime.d.ts +2 -0
- package/dist/features/runtime/runtime.js +45 -21
- package/dist/features/studio/components/EnvironmentMenu.js +76 -63
- package/dist/features/studio/components/Navbar.js +53 -80
- package/dist/features/vite/auth.js +1 -50
- package/dist/features/vite/iconGeneration.js +16 -0
- package/dist/features/vite/layoutGeneration.js +7 -3
- package/dist/features/vite/vite.d.ts +4 -2
- package/dist/features/vite/vite.js +24 -3
- package/dist/hooks/use-page-destinations.js +53 -0
- package/dist/lib/auth.js +40 -20
- package/dist/lib/preview-handoff.js +13 -0
- package/dist/lib/queries.js +12 -1
- package/dist/lib/server-auth-cookie.js +21 -0
- package/dist/lib/use-project-room.js +5 -2
- package/dist/studio-overlays.css +19 -15
- package/dist/studio.css +1 -1
- package/package.json +9 -4
- package/skills/camox/SKILL.md +38 -9
- package/skills/camox/references/block-definitions.md +107 -286
- package/skills/camox/references/cli-common.md +16 -4
- package/skills/camox/references/cli-content.md +158 -0
- package/skills/camox/references/cli-environments.md +1 -1
- package/skills/camox/references/dom-integrations.md +93 -0
- package/skills/camox/references/field-styling.md +50 -0
- package/skills/camox/references/layout-definitions.md +33 -147
- package/skills/camox/references/routed-layouts.md +71 -0
- package/skills/camoxify/SKILL.md +66 -0
- package/skills/camox/references/cli-blocks.md +0 -78
- package/skills/camox/references/cli-pages.md +0 -53
|
@@ -5,15 +5,14 @@ import { c } from "react/compiler-runtime";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { useSelector } from "@xstate/store-react";
|
|
8
|
-
import { Kbd } from "@camox/ui/kbd";
|
|
9
8
|
import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandShortcut } from "@camox/ui/command";
|
|
10
9
|
|
|
11
10
|
//#region src/features/provider/components/CommandPalette.tsx
|
|
12
11
|
function CommandPalette() {
|
|
13
|
-
const $ = c(
|
|
14
|
-
if ($[0] !== "
|
|
15
|
-
for (let $i = 0; $i <
|
|
16
|
-
$[0] = "
|
|
12
|
+
const $ = c(37);
|
|
13
|
+
if ($[0] !== "9972e9f574379197af85e2183aa9808df309da92f446247a1c5412a1062393cb") {
|
|
14
|
+
for (let $i = 0; $i < 37; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
15
|
+
$[0] = "9972e9f574379197af85e2183aa9808df309da92f446247a1c5412a1062393cb";
|
|
17
16
|
}
|
|
18
17
|
const isOpen = useSelector(studioStore, _temp);
|
|
19
18
|
const [search, setSearch] = React.useState("");
|
|
@@ -163,64 +162,18 @@ function CommandPalette() {
|
|
|
163
162
|
} else t8 = $[25];
|
|
164
163
|
let t9;
|
|
165
164
|
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
166
|
-
t9 = /* @__PURE__ */
|
|
167
|
-
className: "
|
|
168
|
-
children:
|
|
169
|
-
/* @__PURE__ */ jsx(Kbd, { children: "↑" }),
|
|
170
|
-
/* @__PURE__ */ jsx(Kbd, { children: "↓" }),
|
|
171
|
-
" to navigate"
|
|
172
|
-
]
|
|
165
|
+
t9 = /* @__PURE__ */ jsx(CommandEmpty, {
|
|
166
|
+
className: "text-muted-foreground py-8",
|
|
167
|
+
children: "No results found."
|
|
173
168
|
});
|
|
174
169
|
$[26] = t9;
|
|
175
170
|
} else t9 = $[26];
|
|
176
171
|
let t10;
|
|
177
|
-
if ($[27]
|
|
178
|
-
t10 = /* @__PURE__ */ jsxs(
|
|
179
|
-
className: "flex items-center gap-1.5",
|
|
180
|
-
children: [/* @__PURE__ */ jsx(Kbd, { children: "↵" }), " to select"]
|
|
181
|
-
});
|
|
182
|
-
$[27] = t10;
|
|
183
|
-
} else t10 = $[27];
|
|
184
|
-
let t11;
|
|
185
|
-
if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
|
|
186
|
-
t11 = /* @__PURE__ */ jsx(Kbd, { children: "Esc" });
|
|
187
|
-
$[28] = t11;
|
|
188
|
-
} else t11 = $[28];
|
|
189
|
-
const t12 = page ? "to go back" : "to close";
|
|
190
|
-
let t13;
|
|
191
|
-
if ($[29] !== t12) {
|
|
192
|
-
t13 = /* @__PURE__ */ jsxs("div", {
|
|
193
|
-
className: "text-muted-foreground flex flex-wrap items-center gap-x-4 gap-y-2 border-b px-5 pb-3 text-xs",
|
|
194
|
-
children: [
|
|
195
|
-
t9,
|
|
196
|
-
t10,
|
|
197
|
-
/* @__PURE__ */ jsxs("span", {
|
|
198
|
-
className: "flex items-center gap-1.5",
|
|
199
|
-
children: [
|
|
200
|
-
t11,
|
|
201
|
-
" ",
|
|
202
|
-
t12
|
|
203
|
-
]
|
|
204
|
-
})
|
|
205
|
-
]
|
|
206
|
-
});
|
|
207
|
-
$[29] = t12;
|
|
208
|
-
$[30] = t13;
|
|
209
|
-
} else t13 = $[30];
|
|
210
|
-
let t14;
|
|
211
|
-
if ($[31] === Symbol.for("react.memo_cache_sentinel")) {
|
|
212
|
-
t14 = /* @__PURE__ */ jsx(CommandEmpty, {
|
|
213
|
-
className: "text-muted-foreground py-8",
|
|
214
|
-
children: "No results found."
|
|
215
|
-
});
|
|
216
|
-
$[31] = t14;
|
|
217
|
-
} else t14 = $[31];
|
|
218
|
-
let t15;
|
|
219
|
-
if ($[32] !== groupedActions || $[33] !== handleSelect) {
|
|
220
|
-
t15 = /* @__PURE__ */ jsxs(CommandList, {
|
|
172
|
+
if ($[27] !== groupedActions || $[28] !== handleSelect) {
|
|
173
|
+
t10 = /* @__PURE__ */ jsxs(CommandList, {
|
|
221
174
|
className: "max-h-[min(24rem,45dvh)] min-h-0 scroll-py-1 px-2 pt-1 pb-2",
|
|
222
|
-
children: [
|
|
223
|
-
const [groupLabel_0, groupActions] =
|
|
175
|
+
children: [t9, Array.from(groupedActions.entries()).map((t11) => {
|
|
176
|
+
const [groupLabel_0, groupActions] = t11;
|
|
224
177
|
return /* @__PURE__ */ jsx(CommandGroup, {
|
|
225
178
|
heading: groupLabel_0,
|
|
226
179
|
className: "mb-2 p-0 last:mb-0 **:[[cmdk-group-heading]]:px-3 **:[[cmdk-group-heading]]:py-2 **:[[cmdk-group-heading]]:text-[11px] **:[[cmdk-group-heading]]:tracking-widest **:[[cmdk-group-heading]]:uppercase",
|
|
@@ -234,44 +187,42 @@ function CommandPalette() {
|
|
|
234
187
|
}, groupLabel_0);
|
|
235
188
|
})]
|
|
236
189
|
});
|
|
237
|
-
$[
|
|
238
|
-
$[
|
|
239
|
-
$[
|
|
240
|
-
} else
|
|
241
|
-
let
|
|
242
|
-
if ($[
|
|
243
|
-
|
|
190
|
+
$[27] = groupedActions;
|
|
191
|
+
$[28] = handleSelect;
|
|
192
|
+
$[29] = t10;
|
|
193
|
+
} else t10 = $[29];
|
|
194
|
+
let t11;
|
|
195
|
+
if ($[30] !== t10 || $[31] !== t8 || $[32] !== value) {
|
|
196
|
+
t11 = /* @__PURE__ */ jsxs(Command, {
|
|
244
197
|
value,
|
|
245
198
|
onValueChange: setValue,
|
|
246
199
|
className: "h-auto max-h-[80dvh] p-0",
|
|
247
200
|
children: [
|
|
248
201
|
t6,
|
|
249
202
|
t8,
|
|
250
|
-
|
|
251
|
-
t15
|
|
203
|
+
t10
|
|
252
204
|
]
|
|
253
205
|
});
|
|
254
|
-
$[
|
|
255
|
-
$[
|
|
256
|
-
$[
|
|
257
|
-
$[
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
t17 = /* @__PURE__ */ jsx(CommandDialog, {
|
|
206
|
+
$[30] = t10;
|
|
207
|
+
$[31] = t8;
|
|
208
|
+
$[32] = value;
|
|
209
|
+
$[33] = t11;
|
|
210
|
+
} else t11 = $[33];
|
|
211
|
+
let t12;
|
|
212
|
+
if ($[34] !== isOpen || $[35] !== t11) {
|
|
213
|
+
t12 = /* @__PURE__ */ jsx(CommandDialog, {
|
|
263
214
|
open: isOpen,
|
|
264
215
|
onOpenChange: handleOpenChange,
|
|
265
216
|
className: "top-[12vh] sm:max-w-xl",
|
|
266
217
|
description: "Navigate your site and switch settings quickly.",
|
|
267
218
|
showCloseButton: true,
|
|
268
|
-
children:
|
|
219
|
+
children: t11
|
|
269
220
|
});
|
|
270
|
-
$[
|
|
271
|
-
$[
|
|
272
|
-
$[
|
|
273
|
-
} else
|
|
274
|
-
return
|
|
221
|
+
$[34] = isOpen;
|
|
222
|
+
$[35] = t11;
|
|
223
|
+
$[36] = t12;
|
|
224
|
+
} else t12 = $[36];
|
|
225
|
+
return t12;
|
|
275
226
|
}
|
|
276
227
|
function _temp3(state_1) {
|
|
277
228
|
return state_1.context.commandPalettePages;
|
|
@@ -284,9 +235,9 @@ function _temp(state) {
|
|
|
284
235
|
}
|
|
285
236
|
function useCommandPaletteActions() {
|
|
286
237
|
const $ = c(2);
|
|
287
|
-
if ($[0] !== "
|
|
238
|
+
if ($[0] !== "9972e9f574379197af85e2183aa9808df309da92f446247a1c5412a1062393cb") {
|
|
288
239
|
for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
289
|
-
$[0] = "
|
|
240
|
+
$[0] = "9972e9f574379197af85e2183aa9808df309da92f446247a1c5412a1062393cb";
|
|
290
241
|
}
|
|
291
242
|
let t0;
|
|
292
243
|
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
@@ -14,15 +14,15 @@ import { jsx } from "react/jsx-runtime";
|
|
|
14
14
|
|
|
15
15
|
//#region src/features/runtime/pageApp.tsx
|
|
16
16
|
function PageApp(t0) {
|
|
17
|
-
const $ = c(
|
|
18
|
-
if ($[0] !== "
|
|
19
|
-
for (let $i = 0; $i <
|
|
20
|
-
$[0] = "
|
|
17
|
+
const $ = c(20);
|
|
18
|
+
if ($[0] !== "cc0d298a8943efca3ffb5e7cf2f8f814ebecbf27dec68e2a3129c1bb95c18943") {
|
|
19
|
+
for (let $i = 0; $i < 20; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
20
|
+
$[0] = "cc0d298a8943efca3ffb5e7cf2f8f814ebecbf27dec68e2a3129c1bb95c18943";
|
|
21
21
|
}
|
|
22
22
|
const { camoxApp, input, queryClient } = t0;
|
|
23
23
|
const t1 = input.dehydratedState;
|
|
24
24
|
let t2;
|
|
25
|
-
if ($[1] !== camoxApp || $[2] !== input.apiUrl || $[3] !== input.authenticationUrl || $[4] !== input.environmentName || $[5] !== input.presentation || $[6] !== input.
|
|
25
|
+
if ($[1] !== camoxApp || $[2] !== input.apiUrl || $[3] !== input.authenticationUrl || $[4] !== input.environmentName || $[5] !== input.presentation || $[6] !== input.previewHandoff || $[7] !== input.projectSlug || $[8] !== queryClient) {
|
|
26
26
|
t2 = (currentInput) => /* @__PURE__ */ jsx(CoreCamoxProvider, {
|
|
27
27
|
camoxApp,
|
|
28
28
|
authenticationUrl: input.authenticationUrl,
|
|
@@ -33,7 +33,10 @@ function PageApp(t0) {
|
|
|
33
33
|
initialProject: currentInput.project,
|
|
34
34
|
children: /* @__PURE__ */ jsx(PreviewDocumentContext.Provider, {
|
|
35
35
|
value: currentInput.previewDocument,
|
|
36
|
-
children: /* @__PURE__ */ jsx(
|
|
36
|
+
children: input.previewHandoff ? /* @__PURE__ */ jsx("div", {
|
|
37
|
+
role: "status",
|
|
38
|
+
children: "Signing in to draft preview…"
|
|
39
|
+
}) : /* @__PURE__ */ jsx(PageExperience, {
|
|
37
40
|
camoxApp,
|
|
38
41
|
input: currentInput,
|
|
39
42
|
queryClient,
|
|
@@ -46,42 +49,43 @@ function PageApp(t0) {
|
|
|
46
49
|
$[3] = input.authenticationUrl;
|
|
47
50
|
$[4] = input.environmentName;
|
|
48
51
|
$[5] = input.presentation;
|
|
49
|
-
$[6] = input.
|
|
50
|
-
$[7] =
|
|
51
|
-
$[8] =
|
|
52
|
-
|
|
52
|
+
$[6] = input.previewHandoff;
|
|
53
|
+
$[7] = input.projectSlug;
|
|
54
|
+
$[8] = queryClient;
|
|
55
|
+
$[9] = t2;
|
|
56
|
+
} else t2 = $[9];
|
|
53
57
|
let t3;
|
|
54
|
-
if ($[
|
|
58
|
+
if ($[10] !== input || $[11] !== queryClient || $[12] !== t2) {
|
|
55
59
|
t3 = /* @__PURE__ */ jsx(PageNavigationProvider, {
|
|
56
60
|
initialInput: input,
|
|
57
61
|
queryClient,
|
|
58
62
|
children: t2
|
|
59
63
|
});
|
|
60
|
-
$[
|
|
61
|
-
$[
|
|
62
|
-
$[
|
|
63
|
-
$[
|
|
64
|
-
} else t3 = $[
|
|
64
|
+
$[10] = input;
|
|
65
|
+
$[11] = queryClient;
|
|
66
|
+
$[12] = t2;
|
|
67
|
+
$[13] = t3;
|
|
68
|
+
} else t3 = $[13];
|
|
65
69
|
let t4;
|
|
66
|
-
if ($[
|
|
70
|
+
if ($[14] !== t1 || $[15] !== t3) {
|
|
67
71
|
t4 = /* @__PURE__ */ jsx(HydrationBoundary, {
|
|
68
72
|
state: t1,
|
|
69
73
|
children: t3
|
|
70
74
|
});
|
|
71
|
-
$[
|
|
72
|
-
$[
|
|
73
|
-
$[
|
|
74
|
-
} else t4 = $[
|
|
75
|
+
$[14] = t1;
|
|
76
|
+
$[15] = t3;
|
|
77
|
+
$[16] = t4;
|
|
78
|
+
} else t4 = $[16];
|
|
75
79
|
let t5;
|
|
76
|
-
if ($[
|
|
80
|
+
if ($[17] !== queryClient || $[18] !== t4) {
|
|
77
81
|
t5 = /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
78
82
|
client: queryClient,
|
|
79
83
|
children: t4
|
|
80
84
|
});
|
|
81
|
-
$[
|
|
82
|
-
$[
|
|
83
|
-
$[
|
|
84
|
-
} else t5 = $[
|
|
85
|
+
$[17] = queryClient;
|
|
86
|
+
$[18] = t4;
|
|
87
|
+
$[19] = t5;
|
|
88
|
+
} else t5 = $[19];
|
|
85
89
|
return t5;
|
|
86
90
|
}
|
|
87
91
|
const LazyEditablePageExperience = React.lazy(() => import("../preview/EditablePageExperience.js").then((module) => ({ default: module.EditablePageExperience })));
|
|
@@ -101,9 +105,9 @@ var EditingActivationBoundary = class extends React.Component {
|
|
|
101
105
|
const subscribeToHydration = () => () => {};
|
|
102
106
|
function PageExperience(t0) {
|
|
103
107
|
const $ = c(39);
|
|
104
|
-
if ($[0] !== "
|
|
108
|
+
if ($[0] !== "cc0d298a8943efca3ffb5e7cf2f8f814ebecbf27dec68e2a3129c1bb95c18943") {
|
|
105
109
|
for (let $i = 0; $i < 39; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
106
|
-
$[0] = "
|
|
110
|
+
$[0] = "cc0d298a8943efca3ffb5e7cf2f8f814ebecbf27dec68e2a3129c1bb95c18943";
|
|
107
111
|
}
|
|
108
112
|
const { camoxApp, input, queryClient, studioDocument } = t0;
|
|
109
113
|
const { isAuthenticated, isLoading } = useAuthState();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { prefetchIcons } from "../../core/lib/icons.js";
|
|
1
2
|
import { PageApp } from "./pageApp.js";
|
|
2
|
-
import { QueryClient, hydrate } from "@tanstack/react-query";
|
|
3
|
+
import { QueryClient, dehydrate, hydrate } from "@tanstack/react-query";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
import { renderToString } from "react-dom/server";
|
|
5
6
|
|
|
@@ -7,6 +8,8 @@ import { renderToString } from "react-dom/server";
|
|
|
7
8
|
async function renderPageWithApp(input) {
|
|
8
9
|
const queryClient = new QueryClient();
|
|
9
10
|
hydrate(queryClient, input.dehydratedState);
|
|
11
|
+
await prefetchIcons(queryClient, input.dehydratedState, input.camoxApp.getSerializableDefinitions());
|
|
12
|
+
Object.assign(input.dehydratedState, dehydrate(queryClient));
|
|
10
13
|
return renderToString(/* @__PURE__ */ jsx(PageApp, {
|
|
11
14
|
camoxApp: input.camoxApp,
|
|
12
15
|
input,
|
|
@@ -17,6 +17,8 @@ interface LayoutIdentity {
|
|
|
17
17
|
version: string;
|
|
18
18
|
}
|
|
19
19
|
interface PageRenderInput {
|
|
20
|
+
/** Authenticate before looking up a page that may exist only in draft. */
|
|
21
|
+
previewHandoff?: boolean;
|
|
20
22
|
previewDocument?: string;
|
|
21
23
|
routeKind?: "studio" | "studio-content" | "studio-nested";
|
|
22
24
|
project?: Awaited<ReturnType<ReturnType<typeof createServerApiClient>["projects"]["getBySlug"]>>;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { buildClearServerAuthCookieHeader, getServerAuthCookieHeader } from "../../lib/server-auth-cookie.js";
|
|
2
|
+
import { getPageDestinations } from "../../core/pageDestinations.js";
|
|
1
3
|
import { PLATFORM_SCRIPT } from "../../lib/platform.js";
|
|
2
4
|
import { STUDIO_THEME_SCRIPT } from "../studio/studioTheme.js";
|
|
3
5
|
import { matchDerivedLayout } from "../../core/derivedRoutes.js";
|
|
@@ -9,20 +11,6 @@ import { createHead, renderSSRHead } from "@unhead/react/server";
|
|
|
9
11
|
const DEFAULT_RUNTIME_BASE_PATH = "";
|
|
10
12
|
const RUNTIME_HEALTH_PATH = "/_camox/health";
|
|
11
13
|
const RUNTIME_REGISTRY_PATH = "/_camox/registry";
|
|
12
|
-
const SERVER_AUTH_COOKIE_NAME = "camox_auth_cookie";
|
|
13
|
-
function buildClearServerAuthCookieHeader() {
|
|
14
|
-
return `${SERVER_AUTH_COOKIE_NAME}=; Path=/; SameSite=Lax; Max-Age=0`;
|
|
15
|
-
}
|
|
16
|
-
function getServerAuthCookieHeader(headers) {
|
|
17
|
-
const authCookie = (headers.get("Cookie") ?? headers.get("cookie") ?? "").split(";").map((part) => part.trim()).find((part) => part.startsWith(`${SERVER_AUTH_COOKIE_NAME}=`));
|
|
18
|
-
if (!authCookie) return "";
|
|
19
|
-
const value = authCookie.slice(18);
|
|
20
|
-
try {
|
|
21
|
-
return decodeURIComponent(value);
|
|
22
|
-
} catch {
|
|
23
|
-
return "";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
14
|
function normalizeRuntimeBasePath(basePath) {
|
|
27
15
|
if (basePath === void 0) return DEFAULT_RUNTIME_BASE_PATH;
|
|
28
16
|
if (!basePath || basePath === "/") return "";
|
|
@@ -101,10 +89,16 @@ async function createSitemapResponse(request, options) {
|
|
|
101
89
|
if (!options.apiUrl || !options.projectSlug) return Response.json({ message: "Camox sitemap is not configured." }, { status: 500 });
|
|
102
90
|
const api = createServerApiClient(options.apiUrl, options.environmentName);
|
|
103
91
|
const origin = new URL(request.url).origin;
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
const pages = await api.pages.listBySlug({ projectSlug: options.projectSlug });
|
|
93
|
+
const destinations = getPageDestinations(pages, (await options.getCamoxApp?.())?.getLayouts() ?? []);
|
|
94
|
+
const updatedAtById = new Map(pages.map((page) => [page.id, page.updatedAt]));
|
|
95
|
+
const entries = destinations.map((page) => {
|
|
96
|
+
const updatedAt = page.kind === "curated" ? updatedAtById.get(page.pageId) : void 0;
|
|
97
|
+
const lastmod = updatedAt == null ? "" : `\n <lastmod>${escapeXml(new Date(updatedAt).toISOString())}</lastmod>`;
|
|
98
|
+
return ` <url>
|
|
99
|
+
<loc>${escapeXml(`${origin}${withRuntimeBasePath(page.fullPath, options.runtimeBasePath)}`)}</loc>${lastmod}
|
|
100
|
+
</url>`;
|
|
101
|
+
}).join("\n");
|
|
108
102
|
return new Response(`<?xml version="1.0" encoding="UTF-8"?>
|
|
109
103
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
110
104
|
${entries}
|
|
@@ -214,6 +208,33 @@ async function createPageHtmlResponse({ options, pathname, request }) {
|
|
|
214
208
|
pathname,
|
|
215
209
|
request
|
|
216
210
|
});
|
|
211
|
+
const requestUrl = new URL(request.url);
|
|
212
|
+
if (requestUrl.searchParams.has("camox-preview") && requestUrl.searchParams.has("ott")) {
|
|
213
|
+
const input = {
|
|
214
|
+
previewHandoff: true,
|
|
215
|
+
presentation: "public",
|
|
216
|
+
source: "live",
|
|
217
|
+
apiUrl: options.apiUrl,
|
|
218
|
+
authenticationUrl: options.authenticationUrl,
|
|
219
|
+
environmentName: options.environmentName,
|
|
220
|
+
projectSlug: options.projectSlug,
|
|
221
|
+
href: requestUrl.href,
|
|
222
|
+
pathname,
|
|
223
|
+
runtimeBasePath: normalizeRuntimeBasePath(options.runtimeBasePath),
|
|
224
|
+
head: {},
|
|
225
|
+
loaderData: null,
|
|
226
|
+
layoutIdentity: null,
|
|
227
|
+
dehydratedState: dehydrate(new QueryClient())
|
|
228
|
+
};
|
|
229
|
+
const html = await options.renderPage(input);
|
|
230
|
+
return new Response(`<!doctype html><html><head><meta name="referrer" content="no-referrer"><title>Camox draft preview</title><script id="__CAMOX_DATA__" type="application/json">${serializeJsonForHtml(input)}<\/script></head><body><div id="root">${html}</div>${renderClientEntryScript(options.pageClientEntryUrl)}</body></html>`, { headers: {
|
|
231
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
232
|
+
"Cache-Control": "private, no-store",
|
|
233
|
+
"Referrer-Policy": "no-referrer"
|
|
234
|
+
} });
|
|
235
|
+
}
|
|
236
|
+
const singleton = await createDerivedResponse(options, pathname, request, false, true);
|
|
237
|
+
if (singleton) return singleton;
|
|
217
238
|
const queryClient = new QueryClient();
|
|
218
239
|
try {
|
|
219
240
|
const result = await loadCamoxPageForRequest({
|
|
@@ -277,13 +298,14 @@ ${renderClientEntryScript(options.pageClientEntryUrl)}
|
|
|
277
298
|
throw error;
|
|
278
299
|
}
|
|
279
300
|
}
|
|
280
|
-
async function createDerivedResponse(options, pathname, request, dataOnly = false) {
|
|
301
|
+
async function createDerivedResponse(options, pathname, request, dataOnly = false, singletonOnly = false) {
|
|
281
302
|
const app = await options.getCamoxApp?.();
|
|
282
303
|
const match = app && matchDerivedLayout(app.getLayouts(), pathname);
|
|
283
304
|
if (!match || !dataOnly && !options.renderPage) return null;
|
|
305
|
+
if (singletonOnly && match.layout._internal.kind !== "singleton") return null;
|
|
284
306
|
try {
|
|
285
|
-
const data = await match.layout._internal.loader({ params: match.params });
|
|
286
|
-
const serializedData = JSON.parse(JSON.stringify(data));
|
|
307
|
+
const data = await match.layout._internal.loader?.({ params: match.params });
|
|
308
|
+
const serializedData = data === void 0 ? void 0 : JSON.parse(JSON.stringify(data));
|
|
287
309
|
const queryClient = new QueryClient();
|
|
288
310
|
const authCookieHeader = getServerAuthCookieHeader(request.headers);
|
|
289
311
|
let source = authCookieHeader ? "draft" : "live";
|
|
@@ -404,6 +426,8 @@ ${renderClientEntryScript(options.studioClientEntryUrl)}
|
|
|
404
426
|
}
|
|
405
427
|
async function createPageDataResponse({ options, pathname, request }) {
|
|
406
428
|
if (!options.apiUrl || !options.projectSlug) return Response.json({ message: "Camox page loader is not configured." }, { status: 500 });
|
|
429
|
+
const singleton = await createDerivedResponse(options, pathname, request, true, true);
|
|
430
|
+
if (singleton) return singleton;
|
|
407
431
|
const queryClient = new QueryClient();
|
|
408
432
|
try {
|
|
409
433
|
const result = await loadCamoxPageForRequest({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AuthContext } from "../../../lib/auth.js";
|
|
2
2
|
import { environmentMutations, environmentQueries, projectQueries } from "../../../lib/queries.js";
|
|
3
|
+
import { areCommentsEnabled } from "../../preview/commentsEnabled.js";
|
|
3
4
|
import { c } from "react/compiler-runtime";
|
|
4
5
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
6
|
import * as React from "react";
|
|
@@ -30,15 +31,16 @@ function formatReason(reason, direction) {
|
|
|
30
31
|
case "block-definition-missing-in-source": return `Block type "${reason.blockId}" exists in ${targetLabel} but not in ${sourceLabel}.`;
|
|
31
32
|
case "block-definition-missing-in-target": return `Block type "${reason.blockId}" exists in ${sourceLabel} but not in ${targetLabel}. ${remedy}`;
|
|
32
33
|
case "block-definition-schema-mismatch": return `Block type "${reason.blockId}" has a different "${reason.field}" between envs. Sync block definitions and try again.`;
|
|
34
|
+
case "layout-kind-mismatch": return `Layout "${reason.layoutId}" has a different kind between environments. Sync layout definitions and try again.`;
|
|
33
35
|
case "layout-missing-in-source": return `Layout "${reason.layoutId}" exists in ${targetLabel} but not in ${sourceLabel}.`;
|
|
34
36
|
case "layout-missing-in-target": return `Layout "${reason.layoutId}" exists in ${sourceLabel} but not in ${targetLabel}. ${remedy}`;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
const EnvironmentMenu = () => {
|
|
38
|
-
const $ = c(
|
|
39
|
-
if ($[0] !== "
|
|
40
|
-
for (let $i = 0; $i <
|
|
41
|
-
$[0] = "
|
|
40
|
+
const $ = c(87);
|
|
41
|
+
if ($[0] !== "a19764fc2cadba3ca96828ce487913043214419dfe0474e5a0ab5e6e8d2d6177") {
|
|
42
|
+
for (let $i = 0; $i < 87; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
43
|
+
$[0] = "a19764fc2cadba3ca96828ce487913043214419dfe0474e5a0ab5e6e8d2d6177";
|
|
42
44
|
}
|
|
43
45
|
const [open, setOpen] = React.useState(false);
|
|
44
46
|
const [pendingDirection, setPendingDirection] = React.useState(null);
|
|
@@ -301,7 +303,7 @@ const EnvironmentMenu = () => {
|
|
|
301
303
|
} else t25 = $[55];
|
|
302
304
|
let t26;
|
|
303
305
|
if ($[56] !== environmentName || $[57] !== pendingDirection) {
|
|
304
|
-
t26 =
|
|
306
|
+
t26 = pendingDirection === "push" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
305
307
|
"This will replace all content in",
|
|
306
308
|
" ",
|
|
307
309
|
/* @__PURE__ */ jsx("span", {
|
|
@@ -328,84 +330,95 @@ const EnvironmentMenu = () => {
|
|
|
328
330
|
children: "production"
|
|
329
331
|
}),
|
|
330
332
|
". This action cannot be undone."
|
|
331
|
-
] })
|
|
333
|
+
] });
|
|
332
334
|
$[56] = environmentName;
|
|
333
335
|
$[57] = pendingDirection;
|
|
334
336
|
$[58] = t26;
|
|
335
337
|
} else t26 = $[58];
|
|
336
338
|
let t27;
|
|
337
|
-
if ($[59]
|
|
338
|
-
t27 =
|
|
339
|
-
$[59] =
|
|
340
|
-
|
|
341
|
-
$[61] = t27;
|
|
342
|
-
} else t27 = $[61];
|
|
339
|
+
if ($[59] === Symbol.for("react.memo_cache_sentinel")) {
|
|
340
|
+
t27 = areCommentsEnabled() && " Feedback comments in the destination will also be replaced.";
|
|
341
|
+
$[59] = t27;
|
|
342
|
+
} else t27 = $[59];
|
|
343
343
|
let t28;
|
|
344
|
-
if ($[
|
|
345
|
-
t28 = /* @__PURE__ */
|
|
344
|
+
if ($[60] !== t26) {
|
|
345
|
+
t28 = /* @__PURE__ */ jsxs(AlertDialogDescription, { children: [t26, t27] });
|
|
346
|
+
$[60] = t26;
|
|
347
|
+
$[61] = t28;
|
|
348
|
+
} else t28 = $[61];
|
|
349
|
+
let t29;
|
|
350
|
+
if ($[62] !== t25 || $[63] !== t28) {
|
|
351
|
+
t29 = /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [t25, t28] });
|
|
352
|
+
$[62] = t25;
|
|
353
|
+
$[63] = t28;
|
|
354
|
+
$[64] = t29;
|
|
355
|
+
} else t29 = $[64];
|
|
356
|
+
let t30;
|
|
357
|
+
if ($[65] !== replicate.isPending) {
|
|
358
|
+
t30 = /* @__PURE__ */ jsx(AlertDialogCancel, {
|
|
346
359
|
variant: "outline",
|
|
347
360
|
size: "default",
|
|
348
361
|
disabled: replicate.isPending,
|
|
349
362
|
children: "Cancel"
|
|
350
363
|
});
|
|
351
|
-
$[
|
|
352
|
-
$[
|
|
353
|
-
} else
|
|
354
|
-
let t29;
|
|
355
|
-
if ($[64] !== replicate.isPending) {
|
|
356
|
-
t29 = replicate.isPending ? /* @__PURE__ */ jsx(Spinner, {}) : null;
|
|
357
|
-
$[64] = replicate.isPending;
|
|
358
|
-
$[65] = t29;
|
|
359
|
-
} else t29 = $[65];
|
|
360
|
-
const t30 = pendingDirection === "push" ? "Push" : "Pull";
|
|
364
|
+
$[65] = replicate.isPending;
|
|
365
|
+
$[66] = t30;
|
|
366
|
+
} else t30 = $[66];
|
|
361
367
|
let t31;
|
|
362
|
-
if ($[
|
|
363
|
-
t31 = /* @__PURE__ */
|
|
368
|
+
if ($[67] !== replicate.isPending) {
|
|
369
|
+
t31 = replicate.isPending ? /* @__PURE__ */ jsx(Spinner, {}) : null;
|
|
370
|
+
$[67] = replicate.isPending;
|
|
371
|
+
$[68] = t31;
|
|
372
|
+
} else t31 = $[68];
|
|
373
|
+
const t32 = pendingDirection === "push" ? "Push" : "Pull";
|
|
374
|
+
let t33;
|
|
375
|
+
if ($[69] !== handleConfirm || $[70] !== replicate.isPending || $[71] !== t31 || $[72] !== t32) {
|
|
376
|
+
t33 = /* @__PURE__ */ jsxs(AlertDialogAction, {
|
|
364
377
|
variant: "destructive",
|
|
365
378
|
onClick: handleConfirm,
|
|
366
379
|
disabled: replicate.isPending,
|
|
367
|
-
children: [
|
|
380
|
+
children: [t31, t32]
|
|
368
381
|
});
|
|
369
|
-
$[
|
|
370
|
-
$[
|
|
371
|
-
$[
|
|
372
|
-
$[
|
|
373
|
-
$[
|
|
374
|
-
} else
|
|
375
|
-
let t32;
|
|
376
|
-
if ($[71] !== t28 || $[72] !== t31) {
|
|
377
|
-
t32 = /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [t28, t31] });
|
|
378
|
-
$[71] = t28;
|
|
379
|
-
$[72] = t31;
|
|
380
|
-
$[73] = t32;
|
|
381
|
-
} else t32 = $[73];
|
|
382
|
-
let t33;
|
|
383
|
-
if ($[74] !== t27 || $[75] !== t32) {
|
|
384
|
-
t33 = /* @__PURE__ */ jsxs(AlertDialogContent, { children: [t27, t32] });
|
|
385
|
-
$[74] = t27;
|
|
386
|
-
$[75] = t32;
|
|
387
|
-
$[76] = t33;
|
|
388
|
-
} else t33 = $[76];
|
|
382
|
+
$[69] = handleConfirm;
|
|
383
|
+
$[70] = replicate.isPending;
|
|
384
|
+
$[71] = t31;
|
|
385
|
+
$[72] = t32;
|
|
386
|
+
$[73] = t33;
|
|
387
|
+
} else t33 = $[73];
|
|
389
388
|
let t34;
|
|
390
|
-
if ($[
|
|
391
|
-
t34 = /* @__PURE__ */
|
|
389
|
+
if ($[74] !== t30 || $[75] !== t33) {
|
|
390
|
+
t34 = /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [t30, t33] });
|
|
391
|
+
$[74] = t30;
|
|
392
|
+
$[75] = t33;
|
|
393
|
+
$[76] = t34;
|
|
394
|
+
} else t34 = $[76];
|
|
395
|
+
let t35;
|
|
396
|
+
if ($[77] !== t29 || $[78] !== t34) {
|
|
397
|
+
t35 = /* @__PURE__ */ jsxs(AlertDialogContent, { children: [t29, t34] });
|
|
398
|
+
$[77] = t29;
|
|
399
|
+
$[78] = t34;
|
|
400
|
+
$[79] = t35;
|
|
401
|
+
} else t35 = $[79];
|
|
402
|
+
let t36;
|
|
403
|
+
if ($[80] !== t22 || $[81] !== t23 || $[82] !== t35) {
|
|
404
|
+
t36 = /* @__PURE__ */ jsx(AlertDialog, {
|
|
392
405
|
open: t22,
|
|
393
406
|
onOpenChange: t23,
|
|
394
|
-
children:
|
|
407
|
+
children: t35
|
|
395
408
|
});
|
|
396
|
-
$[
|
|
397
|
-
$[
|
|
398
|
-
$[
|
|
399
|
-
$[
|
|
400
|
-
} else
|
|
401
|
-
let
|
|
402
|
-
if ($[
|
|
403
|
-
|
|
404
|
-
$[
|
|
405
|
-
$[
|
|
406
|
-
$[
|
|
407
|
-
} else
|
|
408
|
-
return
|
|
409
|
+
$[80] = t22;
|
|
410
|
+
$[81] = t23;
|
|
411
|
+
$[82] = t35;
|
|
412
|
+
$[83] = t36;
|
|
413
|
+
} else t36 = $[83];
|
|
414
|
+
let t37;
|
|
415
|
+
if ($[84] !== t21 || $[85] !== t36) {
|
|
416
|
+
t37 = /* @__PURE__ */ jsxs(Fragment, { children: [t21, t36] });
|
|
417
|
+
$[84] = t21;
|
|
418
|
+
$[85] = t36;
|
|
419
|
+
$[86] = t37;
|
|
420
|
+
} else t37 = $[86];
|
|
421
|
+
return t37;
|
|
409
422
|
};
|
|
410
423
|
|
|
411
424
|
//#endregion
|