camox 0.41.1 → 0.43.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/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 +6 -6
- package/dist/core/components/lexical/SelectionBroadcaster.js +5 -5
- package/dist/core/components/lexical/SidebarLexicalEditor.js +52 -49
- package/dist/core/components/lexical/TextLinkPopover.js +191 -208
- package/dist/core/components/lexical/editorConfig.js +2 -2
- package/dist/core/createApp.d.ts +19 -4
- package/dist/core/createApp.js +2 -1
- 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 +8 -1
- package/dist/core/editing/createEditableBlock.js +636 -459
- package/dist/core/hooks/useOverlayState.js +11 -0
- package/dist/core/lib/fieldTypes.js +5 -5
- package/dist/core/lib/lexicalReact.js +4 -4
- package/dist/core/lib/lexicalState.js +20 -4
- package/dist/core/lib/modifierFormats.js +1 -1
- package/dist/core/lib/textLinks.js +5 -2
- package/dist/core/lib/textStyles.d.ts +2 -2
- package/dist/core/lib/textStyles.js +6 -11
- package/dist/core/pageDestinations.js +37 -0
- package/dist/features/og/imageResponse.node.js +11 -9
- package/dist/features/preview/CamoxPreview.js +108 -124
- package/dist/features/preview/commentsEnabled.js +8 -0
- package/dist/features/preview/components/AddBlockSidebar.js +80 -90
- package/dist/features/preview/components/AssetLightbox.js +4 -11
- package/dist/features/preview/components/AttachedComments.js +194 -0
- package/dist/features/preview/components/BlockActionsPopover.js +14 -65
- package/dist/features/preview/components/CommentHeader.js +122 -0
- package/dist/features/preview/components/CommentSidebar.js +29 -0
- package/dist/features/preview/components/CommentTargetQuote.js +166 -0
- package/dist/features/preview/components/CreatePageModal.js +4 -10
- package/dist/features/preview/components/DerivedLayoutSidebar.js +45 -26
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +38 -26
- package/dist/features/preview/components/FieldToolbar.js +7 -7
- package/dist/features/preview/components/ItemFieldsEditor.js +275 -204
- package/dist/features/preview/components/LeftSidebar.js +18 -18
- package/dist/features/preview/components/LinkFieldEditor.js +212 -209
- package/dist/features/preview/components/OverlayTracker.js +14 -20
- package/dist/features/preview/components/Overlays.js +26 -35
- package/dist/features/preview/components/PageEditorSidebar.js +90 -91
- package/dist/features/preview/components/PageInfoSidebar.js +128 -159
- package/dist/features/preview/components/PagePicker.js +29 -24
- package/dist/features/preview/components/PageTree.js +159 -157
- package/dist/features/preview/components/PreviewComments.js +56 -0
- package/dist/features/preview/components/PreviewPanel.js +122 -78
- package/dist/features/preview/components/PreviewToolbar.js +280 -231
- package/dist/features/preview/components/PublicationRow.js +8 -11
- package/dist/features/preview/components/RightSidebar.js +14 -11
- package/dist/features/preview/components/SidebarSection.js +121 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +1 -1
- package/dist/features/preview/previewCommentsStore.js +115 -0
- package/dist/features/preview/previewSelection.js +75 -0
- package/dist/features/preview/previewStore.js +19 -39
- package/dist/features/preview/publication.js +10 -0
- package/dist/features/provider/AuthenticatedCamoxProvider.js +46 -34
- package/dist/features/provider/CoreCamoxProvider.js +1 -1
- package/dist/features/provider/components/CommandPalette.js +142 -58
- package/dist/features/provider/useAdminShortcuts.js +19 -8
- package/dist/features/routes/pageRuntime.js +0 -6
- package/dist/features/runtime/RuntimeChrome.js +40 -37
- package/dist/features/runtime/runtime.js +20 -21
- package/dist/features/studio/CamoxStudio.js +30 -50
- package/dist/features/studio/components/EnvironmentMenu.js +3 -2
- package/dist/features/studio/components/Navbar.js +53 -80
- package/dist/features/vite/layoutGeneration.js +7 -3
- package/dist/features/vite/runtimeDev.js +4 -1
- package/dist/features/vite/vite.d.ts +3 -2
- package/dist/features/vite/vite.js +14 -6
- package/dist/hooks/use-file-upload.js +0 -2
- package/dist/hooks/use-page-destinations.js +53 -0
- package/dist/lib/auth.js +11 -14
- package/dist/lib/server-auth-cookie.js +21 -0
- package/dist/studio.css +1 -1
- package/package.json +9 -7
- package/skills/camox/SKILL.md +32 -9
- package/skills/camox/references/block-definitions.md +84 -290
- package/skills/camox/references/cli-common.md +2 -4
- package/skills/camox/references/cli-content.md +147 -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 +52 -0
- package/dist/lib/telemetry-client.js +0 -66
- package/dist/lib/telemetry.js +0 -26
- package/skills/camox/references/cli-blocks.md +0 -78
- package/skills/camox/references/cli-pages.md +0 -53
|
@@ -5,14 +5,15 @@ 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";
|
|
8
9
|
import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandShortcut } from "@camox/ui/command";
|
|
9
10
|
|
|
10
11
|
//#region src/features/provider/components/CommandPalette.tsx
|
|
11
12
|
function CommandPalette() {
|
|
12
|
-
const $ = c(
|
|
13
|
-
if ($[0] !== "
|
|
14
|
-
for (let $i = 0; $i <
|
|
15
|
-
$[0] = "
|
|
13
|
+
const $ = c(43);
|
|
14
|
+
if ($[0] !== "911725dec1e42161265ff27436f9ae9c6c82392d2b8fce53f3eb80dfb29cb6f0") {
|
|
15
|
+
for (let $i = 0; $i < 43; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
16
|
+
$[0] = "911725dec1e42161265ff27436f9ae9c6c82392d2b8fce53f3eb80dfb29cb6f0";
|
|
16
17
|
}
|
|
17
18
|
const isOpen = useSelector(studioStore, _temp);
|
|
18
19
|
const [search, setSearch] = React.useState("");
|
|
@@ -119,75 +120,158 @@ function CommandPalette() {
|
|
|
119
120
|
} else t5 = $[19];
|
|
120
121
|
const handleOpenChange = t5;
|
|
121
122
|
let t6;
|
|
122
|
-
if ($[20]
|
|
123
|
-
t6 = (
|
|
123
|
+
if ($[20] === Symbol.for("react.memo_cache_sentinel")) {
|
|
124
|
+
t6 = /* @__PURE__ */ jsxs("div", {
|
|
125
|
+
className: "px-5 pt-5 pr-14 pb-3",
|
|
126
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
127
|
+
className: "text-lg font-semibold tracking-tight",
|
|
128
|
+
children: "Command palette"
|
|
129
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
130
|
+
className: "text-muted-foreground mt-1 text-sm",
|
|
131
|
+
children: "Navigate your site and switch settings quickly."
|
|
132
|
+
})]
|
|
133
|
+
});
|
|
134
|
+
$[20] = t6;
|
|
135
|
+
} else t6 = $[20];
|
|
136
|
+
let t7;
|
|
137
|
+
if ($[21] !== search) {
|
|
138
|
+
t7 = (e) => {
|
|
124
139
|
if (e.key === "Escape" || e.key === "Backspace" && !search) {
|
|
125
140
|
e.preventDefault();
|
|
126
141
|
studioStore.send({ type: "popCommandPalettePage" });
|
|
127
142
|
}
|
|
128
143
|
};
|
|
129
|
-
$[
|
|
130
|
-
$[
|
|
131
|
-
} else
|
|
132
|
-
let
|
|
133
|
-
if ($[
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
$[21] = search;
|
|
145
|
+
$[22] = t7;
|
|
146
|
+
} else t7 = $[22];
|
|
147
|
+
let t8;
|
|
148
|
+
if ($[23] !== search || $[24] !== t7) {
|
|
149
|
+
t8 = /* @__PURE__ */ jsx("div", {
|
|
150
|
+
className: "px-4 pb-4",
|
|
151
|
+
children: /* @__PURE__ */ jsx(CommandInput, {
|
|
152
|
+
className: "placeholder:text-muted-foreground h-full text-base",
|
|
153
|
+
inputGroupClassName: "h-11! border-2 border-primary bg-background rounded-xl! *:data-[slot=input-group-addon]:pl-4!",
|
|
154
|
+
value: search,
|
|
155
|
+
onValueChange: setSearch,
|
|
156
|
+
placeholder: "Type a command or search...",
|
|
157
|
+
onKeyDown: t7
|
|
158
|
+
})
|
|
139
159
|
});
|
|
140
|
-
$[
|
|
141
|
-
$[23] = t6;
|
|
160
|
+
$[23] = search;
|
|
142
161
|
$[24] = t7;
|
|
143
|
-
} else t7 = $[24];
|
|
144
|
-
let t8;
|
|
145
|
-
if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
|
|
146
|
-
t8 = /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." });
|
|
147
162
|
$[25] = t8;
|
|
148
163
|
} else t8 = $[25];
|
|
149
164
|
let t9;
|
|
150
|
-
if ($[26]
|
|
151
|
-
t9 = /* @__PURE__ */ jsxs(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}, groupLabel_0);
|
|
162
|
-
})] });
|
|
163
|
-
$[26] = groupedActions;
|
|
164
|
-
$[27] = handleSelect;
|
|
165
|
-
$[28] = t9;
|
|
166
|
-
} else t9 = $[28];
|
|
165
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
166
|
+
t9 = /* @__PURE__ */ jsxs("span", {
|
|
167
|
+
className: "flex items-center gap-1.5",
|
|
168
|
+
children: [
|
|
169
|
+
/* @__PURE__ */ jsx(Kbd, { children: "↑" }),
|
|
170
|
+
/* @__PURE__ */ jsx(Kbd, { children: "↓" }),
|
|
171
|
+
" to navigate"
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
$[26] = t9;
|
|
175
|
+
} else t9 = $[26];
|
|
167
176
|
let t10;
|
|
168
|
-
if ($[
|
|
169
|
-
t10 = /* @__PURE__ */ jsxs(
|
|
177
|
+
if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
|
|
178
|
+
t10 = /* @__PURE__ */ jsxs("span", {
|
|
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, {
|
|
221
|
+
className: "max-h-[min(24rem,45dvh)] min-h-0 scroll-py-1 px-2 pt-1 pb-2",
|
|
222
|
+
children: [t14, Array.from(groupedActions.entries()).map((t16) => {
|
|
223
|
+
const [groupLabel_0, groupActions] = t16;
|
|
224
|
+
return /* @__PURE__ */ jsx(CommandGroup, {
|
|
225
|
+
heading: groupLabel_0,
|
|
226
|
+
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",
|
|
227
|
+
children: groupActions.map((action_2) => /* @__PURE__ */ jsxs(CommandItem, {
|
|
228
|
+
keywords: action_2.aliases,
|
|
229
|
+
onSelect: () => handleSelect(action_2.id),
|
|
230
|
+
className: "min-h-10 justify-between gap-3 px-3 py-2 text-sm",
|
|
231
|
+
hideCheck: true,
|
|
232
|
+
children: [action_2.label, action_2.shortcut && /* @__PURE__ */ jsx(CommandShortcut, { children: formatShortcut(action_2.shortcut) })]
|
|
233
|
+
}, action_2.id))
|
|
234
|
+
}, groupLabel_0);
|
|
235
|
+
})]
|
|
236
|
+
});
|
|
237
|
+
$[32] = groupedActions;
|
|
238
|
+
$[33] = handleSelect;
|
|
239
|
+
$[34] = t15;
|
|
240
|
+
} else t15 = $[34];
|
|
241
|
+
let t16;
|
|
242
|
+
if ($[35] !== t13 || $[36] !== t15 || $[37] !== t8 || $[38] !== value) {
|
|
243
|
+
t16 = /* @__PURE__ */ jsxs(Command, {
|
|
170
244
|
value,
|
|
171
245
|
onValueChange: setValue,
|
|
172
|
-
|
|
246
|
+
className: "h-auto max-h-[80dvh] p-0",
|
|
247
|
+
children: [
|
|
248
|
+
t6,
|
|
249
|
+
t8,
|
|
250
|
+
t13,
|
|
251
|
+
t15
|
|
252
|
+
]
|
|
173
253
|
});
|
|
174
|
-
$[
|
|
175
|
-
$[
|
|
176
|
-
$[
|
|
177
|
-
$[
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
254
|
+
$[35] = t13;
|
|
255
|
+
$[36] = t15;
|
|
256
|
+
$[37] = t8;
|
|
257
|
+
$[38] = value;
|
|
258
|
+
$[39] = t16;
|
|
259
|
+
} else t16 = $[39];
|
|
260
|
+
let t17;
|
|
261
|
+
if ($[40] !== isOpen || $[41] !== t16) {
|
|
262
|
+
t17 = /* @__PURE__ */ jsx(CommandDialog, {
|
|
182
263
|
open: isOpen,
|
|
183
264
|
onOpenChange: handleOpenChange,
|
|
184
|
-
|
|
265
|
+
className: "top-[12vh] sm:max-w-xl",
|
|
266
|
+
description: "Navigate your site and switch settings quickly.",
|
|
267
|
+
showCloseButton: true,
|
|
268
|
+
children: t16
|
|
185
269
|
});
|
|
186
|
-
$[
|
|
187
|
-
$[
|
|
188
|
-
$[
|
|
189
|
-
} else
|
|
190
|
-
return
|
|
270
|
+
$[40] = isOpen;
|
|
271
|
+
$[41] = t16;
|
|
272
|
+
$[42] = t17;
|
|
273
|
+
} else t17 = $[42];
|
|
274
|
+
return t17;
|
|
191
275
|
}
|
|
192
276
|
function _temp3(state_1) {
|
|
193
277
|
return state_1.context.commandPalettePages;
|
|
@@ -200,9 +284,9 @@ function _temp(state) {
|
|
|
200
284
|
}
|
|
201
285
|
function useCommandPaletteActions() {
|
|
202
286
|
const $ = c(2);
|
|
203
|
-
if ($[0] !== "
|
|
287
|
+
if ($[0] !== "911725dec1e42161265ff27436f9ae9c6c82392d2b8fce53f3eb80dfb29cb6f0") {
|
|
204
288
|
for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
205
|
-
$[0] = "
|
|
289
|
+
$[0] = "911725dec1e42161265ff27436f9ae9c6c82392d2b8fce53f3eb80dfb29cb6f0";
|
|
206
290
|
}
|
|
207
291
|
let t0;
|
|
208
292
|
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
@@ -10,9 +10,9 @@ import { useSelector } from "@xstate/store-react";
|
|
|
10
10
|
*/
|
|
11
11
|
function useAdminShortcuts() {
|
|
12
12
|
const $ = c(4);
|
|
13
|
-
if ($[0] !== "
|
|
13
|
+
if ($[0] !== "bebc7f337697130a10955205113d613ef306f5f46f2a4a506e5e0a4faba82906") {
|
|
14
14
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
15
|
-
$[0] = "
|
|
15
|
+
$[0] = "bebc7f337697130a10955205113d613ef306f5f46f2a4a506e5e0a4faba82906";
|
|
16
16
|
}
|
|
17
17
|
const actions = useSelector(actionsStore, _temp);
|
|
18
18
|
let t0;
|
|
@@ -29,24 +29,35 @@ function useAdminShortcuts() {
|
|
|
29
29
|
if (!matchingAction) return;
|
|
30
30
|
const shortcut = matchingAction.shortcut;
|
|
31
31
|
if (checkIfInputFocused()) {
|
|
32
|
-
if (!shortcut.withMeta && !shortcut.withAlt) return;
|
|
32
|
+
if (shortcut.key !== "Escape" && !shortcut.withMeta && !shortcut.withAlt) return;
|
|
33
33
|
if (shortcut.key === "Backspace") return;
|
|
34
34
|
}
|
|
35
35
|
event.preventDefault();
|
|
36
36
|
event.stopPropagation();
|
|
37
|
+
if (shortcut.key === "Escape" && checkIfInputFocused()) document.activeElement.blur();
|
|
37
38
|
matchingAction.execute();
|
|
38
39
|
};
|
|
39
|
-
const
|
|
40
|
-
if (event_0.
|
|
41
|
-
|
|
40
|
+
const handleCapturedKeyDown = (event_0) => {
|
|
41
|
+
if (event_0.key === "Escape") return;
|
|
42
|
+
handleKeyDown(event_0);
|
|
43
|
+
};
|
|
44
|
+
const handleEscape = (event_1) => {
|
|
45
|
+
if (event_1.key !== "Escape" || event_1.defaultPrevented) return;
|
|
46
|
+
handleKeyDown(event_1);
|
|
47
|
+
};
|
|
48
|
+
const handleMessage = (event_2) => {
|
|
49
|
+
if (event_2.data?.type === "executeAction") {
|
|
50
|
+
const { actionId } = event_2.data;
|
|
42
51
|
const action_0 = actions.find((a) => a.id === actionId);
|
|
43
52
|
if (action_0) action_0.execute();
|
|
44
53
|
}
|
|
45
54
|
};
|
|
46
|
-
document.addEventListener("keydown",
|
|
55
|
+
document.addEventListener("keydown", handleCapturedKeyDown, true);
|
|
56
|
+
window.addEventListener("keydown", handleEscape);
|
|
47
57
|
window.addEventListener("message", handleMessage);
|
|
48
58
|
return () => {
|
|
49
|
-
document.removeEventListener("keydown",
|
|
59
|
+
document.removeEventListener("keydown", handleCapturedKeyDown, true);
|
|
60
|
+
window.removeEventListener("keydown", handleEscape);
|
|
50
61
|
window.removeEventListener("message", handleMessage);
|
|
51
62
|
};
|
|
52
63
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { trackEvent } from "../../lib/telemetry.js";
|
|
2
1
|
import { queryKeys } from "@camox/api-contract/query-keys";
|
|
3
2
|
import { createORPCClient } from "@orpc/client";
|
|
4
3
|
import { RPCLink } from "@orpc/client/fetch";
|
|
@@ -176,11 +175,6 @@ async function createMarkdownResponse({ apiUrl, environmentName, pathname, proje
|
|
|
176
175
|
});
|
|
177
176
|
const { markdown } = await api.blocks.getPageMarkdown({ pageId: page.page.id });
|
|
178
177
|
if (!markdown) return null;
|
|
179
|
-
trackEvent("markdown_served", {
|
|
180
|
-
pathname: requestPathname,
|
|
181
|
-
projectId: page.page.projectId,
|
|
182
|
-
projectName: page.projectName
|
|
183
|
-
});
|
|
184
178
|
return new Response(markdown, { headers: { "Content-Type": "text/markdown; charset=utf-8" } });
|
|
185
179
|
} catch {
|
|
186
180
|
return null;
|
|
@@ -12,10 +12,10 @@ import studioCssUrl from "virtual:camox-studio-css";
|
|
|
12
12
|
|
|
13
13
|
//#region src/features/runtime/RuntimeChrome.tsx
|
|
14
14
|
function RuntimeChrome(t0) {
|
|
15
|
-
const $ = c(
|
|
16
|
-
if ($[0] !== "
|
|
17
|
-
for (let $i = 0; $i <
|
|
18
|
-
$[0] = "
|
|
15
|
+
const $ = c(34);
|
|
16
|
+
if ($[0] !== "4f2448cdd08f7a2c7703fe11bfa7e45ebc2f0485d14029a9a68ae33e62958b54") {
|
|
17
|
+
for (let $i = 0; $i < 34; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
18
|
+
$[0] = "4f2448cdd08f7a2c7703fe11bfa7e45ebc2f0485d14029a9a68ae33e62958b54";
|
|
19
19
|
}
|
|
20
20
|
const { input, children } = t0;
|
|
21
21
|
const preview = !input.routeKind;
|
|
@@ -92,54 +92,57 @@ function RuntimeChrome(t0) {
|
|
|
92
92
|
} else t9 = $[19];
|
|
93
93
|
const t10 = !preview;
|
|
94
94
|
const t11 = input.derived ? void 0 : "max-md:hidden";
|
|
95
|
-
const t12 =
|
|
96
|
-
const t13 =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
const t12 = page?.page.id;
|
|
96
|
+
const t13 = preview && !input.derived ? page?.page.status : void 0;
|
|
97
|
+
const t14 = !!page?.page.livePublishedCheckpointId;
|
|
98
|
+
let t15;
|
|
99
|
+
if ($[20] !== t12 || $[21] !== t13 || $[22] !== t14) {
|
|
100
|
+
t15 = /* @__PURE__ */ jsx(PreviewToolbar, {
|
|
101
|
+
pageId: t12,
|
|
102
|
+
pageStatus: t13,
|
|
103
|
+
hasLiveVersion: t14
|
|
102
104
|
});
|
|
103
105
|
$[20] = t12;
|
|
104
106
|
$[21] = t13;
|
|
105
107
|
$[22] = t14;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
$[23] = t15;
|
|
109
|
+
} else t15 = $[23];
|
|
110
|
+
let t16;
|
|
111
|
+
if ($[24] !== t10 || $[25] !== t11 || $[26] !== t15) {
|
|
112
|
+
t16 = /* @__PURE__ */ jsx("div", {
|
|
110
113
|
hidden: t10,
|
|
111
114
|
className: t11,
|
|
112
|
-
children:
|
|
115
|
+
children: t15
|
|
113
116
|
});
|
|
114
|
-
$[
|
|
115
|
-
$[
|
|
116
|
-
$[25] = t14;
|
|
117
|
+
$[24] = t10;
|
|
118
|
+
$[25] = t11;
|
|
117
119
|
$[26] = t15;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
$[27] = t16;
|
|
121
|
+
} else t16 = $[27];
|
|
122
|
+
let t17;
|
|
123
|
+
if ($[28] !== t16 || $[29] !== t9) {
|
|
124
|
+
t17 = /* @__PURE__ */ jsxs("div", {
|
|
122
125
|
className: "relative flex min-h-0 flex-1 flex-col",
|
|
123
|
-
children: [t9,
|
|
126
|
+
children: [t9, t16]
|
|
124
127
|
});
|
|
125
|
-
$[
|
|
126
|
-
$[
|
|
127
|
-
$[
|
|
128
|
-
} else
|
|
129
|
-
let
|
|
130
|
-
if ($[
|
|
131
|
-
|
|
128
|
+
$[28] = t16;
|
|
129
|
+
$[29] = t9;
|
|
130
|
+
$[30] = t17;
|
|
131
|
+
} else t17 = $[30];
|
|
132
|
+
let t18;
|
|
133
|
+
if ($[31] !== t17 || $[32] !== t8) {
|
|
134
|
+
t18 = /* @__PURE__ */ jsxs(SharedChromeContext.Provider, {
|
|
132
135
|
value: true,
|
|
133
136
|
children: [t4, /* @__PURE__ */ jsxs("div", {
|
|
134
137
|
className: "bg-background flex h-screen flex-col overflow-hidden",
|
|
135
|
-
children: [t8,
|
|
138
|
+
children: [t8, t17]
|
|
136
139
|
})]
|
|
137
140
|
});
|
|
138
|
-
$[
|
|
139
|
-
$[
|
|
140
|
-
$[
|
|
141
|
-
} else
|
|
142
|
-
return
|
|
141
|
+
$[31] = t17;
|
|
142
|
+
$[32] = t8;
|
|
143
|
+
$[33] = t18;
|
|
144
|
+
} else t18 = $[33];
|
|
145
|
+
return t18;
|
|
143
146
|
}
|
|
144
147
|
function _temp(state) {
|
|
145
148
|
return state.context.isToolbarHidden;
|
|
@@ -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,8 @@ async function createPageHtmlResponse({ options, pathname, request }) {
|
|
|
214
208
|
pathname,
|
|
215
209
|
request
|
|
216
210
|
});
|
|
211
|
+
const singleton = await createDerivedResponse(options, pathname, request, false, true);
|
|
212
|
+
if (singleton) return singleton;
|
|
217
213
|
const queryClient = new QueryClient();
|
|
218
214
|
try {
|
|
219
215
|
const result = await loadCamoxPageForRequest({
|
|
@@ -277,13 +273,14 @@ ${renderClientEntryScript(options.pageClientEntryUrl)}
|
|
|
277
273
|
throw error;
|
|
278
274
|
}
|
|
279
275
|
}
|
|
280
|
-
async function createDerivedResponse(options, pathname, request, dataOnly = false) {
|
|
276
|
+
async function createDerivedResponse(options, pathname, request, dataOnly = false, singletonOnly = false) {
|
|
281
277
|
const app = await options.getCamoxApp?.();
|
|
282
278
|
const match = app && matchDerivedLayout(app.getLayouts(), pathname);
|
|
283
279
|
if (!match || !dataOnly && !options.renderPage) return null;
|
|
280
|
+
if (singletonOnly && match.layout._internal.kind !== "singleton") return null;
|
|
284
281
|
try {
|
|
285
|
-
const data = await match.layout._internal.loader({ params: match.params });
|
|
286
|
-
const serializedData = JSON.parse(JSON.stringify(data));
|
|
282
|
+
const data = await match.layout._internal.loader?.({ params: match.params });
|
|
283
|
+
const serializedData = data === void 0 ? void 0 : JSON.parse(JSON.stringify(data));
|
|
287
284
|
const queryClient = new QueryClient();
|
|
288
285
|
const authCookieHeader = getServerAuthCookieHeader(request.headers);
|
|
289
286
|
let source = authCookieHeader ? "draft" : "live";
|
|
@@ -404,6 +401,8 @@ ${renderClientEntryScript(options.studioClientEntryUrl)}
|
|
|
404
401
|
}
|
|
405
402
|
async function createPageDataResponse({ options, pathname, request }) {
|
|
406
403
|
if (!options.apiUrl || !options.projectSlug) return Response.json({ message: "Camox page loader is not configured." }, { status: 500 });
|
|
404
|
+
const singleton = await createDerivedResponse(options, pathname, request, true, true);
|
|
405
|
+
if (singleton) return singleton;
|
|
407
406
|
const queryClient = new QueryClient();
|
|
408
407
|
try {
|
|
409
408
|
const result = await loadCamoxPageForRequest({
|
|
@@ -2,7 +2,6 @@ import { Navigate, useLocation } from "../navigation/navigation.js";
|
|
|
2
2
|
import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
|
|
3
3
|
import { SharedChromeContext } from "../runtime/SharedChromeContext.js";
|
|
4
4
|
import { STUDIO_BASE_PATH } from "./routes.js";
|
|
5
|
-
import { trackClientEvent } from "../../lib/telemetry-client.js";
|
|
6
5
|
import { Navbar } from "./components/Navbar.js";
|
|
7
6
|
import { c } from "react/compiler-runtime";
|
|
8
7
|
import * as React from "react";
|
|
@@ -10,10 +9,10 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
9
|
|
|
11
10
|
//#region src/features/studio/CamoxStudio.tsx
|
|
12
11
|
const CamoxStudio = (t0) => {
|
|
13
|
-
const $ = c(
|
|
14
|
-
if ($[0] !== "
|
|
15
|
-
for (let $i = 0; $i <
|
|
16
|
-
$[0] = "
|
|
12
|
+
const $ = c(12);
|
|
13
|
+
if ($[0] !== "5f0b5c1c244f7af982fa1d0e99a04fcbc60b872999562c3737760c88a71ce1d0") {
|
|
14
|
+
for (let $i = 0; $i < 12; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
15
|
+
$[0] = "5f0b5c1c244f7af982fa1d0e99a04fcbc60b872999562c3737760c88a71ce1d0";
|
|
17
16
|
}
|
|
18
17
|
const { children } = t0;
|
|
19
18
|
const { isAuthenticated, isLoading: isLoadingAuth } = useAuthState();
|
|
@@ -41,61 +40,42 @@ const CamoxStudio = (t0) => {
|
|
|
41
40
|
t2 = $[5];
|
|
42
41
|
}
|
|
43
42
|
React.useEffect(t1, t2);
|
|
44
|
-
const hasTrackedOpenRef = React.useRef(false);
|
|
45
|
-
let t3;
|
|
46
|
-
let t4;
|
|
47
|
-
if ($[6] !== isAuthenticated || $[7] !== pathname) {
|
|
48
|
-
t3 = () => {
|
|
49
|
-
if (!isAuthenticated || hasTrackedOpenRef.current) return;
|
|
50
|
-
hasTrackedOpenRef.current = true;
|
|
51
|
-
trackClientEvent("studio_opened", { route: pathname });
|
|
52
|
-
};
|
|
53
|
-
t4 = [isAuthenticated, pathname];
|
|
54
|
-
$[6] = isAuthenticated;
|
|
55
|
-
$[7] = pathname;
|
|
56
|
-
$[8] = t3;
|
|
57
|
-
$[9] = t4;
|
|
58
|
-
} else {
|
|
59
|
-
t3 = $[8];
|
|
60
|
-
t4 = $[9];
|
|
61
|
-
}
|
|
62
|
-
React.useEffect(t3, t4);
|
|
63
43
|
if (!isAuthenticated) return null;
|
|
64
44
|
if (pathname === STUDIO_BASE_PATH) {
|
|
65
|
-
let
|
|
66
|
-
if ($[
|
|
67
|
-
|
|
45
|
+
let t3;
|
|
46
|
+
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
|
|
47
|
+
t3 = /* @__PURE__ */ jsx(Navigate, {
|
|
68
48
|
to: "/",
|
|
69
49
|
replace: true
|
|
70
50
|
});
|
|
71
|
-
$[
|
|
72
|
-
} else
|
|
73
|
-
return
|
|
51
|
+
$[6] = t3;
|
|
52
|
+
} else t3 = $[6];
|
|
53
|
+
return t3;
|
|
74
54
|
}
|
|
75
55
|
if (sharedChrome) {
|
|
76
|
-
let
|
|
77
|
-
if ($[
|
|
78
|
-
|
|
79
|
-
$[
|
|
80
|
-
$[
|
|
81
|
-
} else
|
|
82
|
-
return
|
|
56
|
+
let t3;
|
|
57
|
+
if ($[7] !== children) {
|
|
58
|
+
t3 = /* @__PURE__ */ jsx(Fragment, { children });
|
|
59
|
+
$[7] = children;
|
|
60
|
+
$[8] = t3;
|
|
61
|
+
} else t3 = $[8];
|
|
62
|
+
return t3;
|
|
83
63
|
}
|
|
84
|
-
let
|
|
85
|
-
if ($[
|
|
86
|
-
|
|
87
|
-
$[
|
|
88
|
-
} else
|
|
89
|
-
let
|
|
90
|
-
if ($[
|
|
91
|
-
|
|
64
|
+
let t3;
|
|
65
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
66
|
+
t3 = /* @__PURE__ */ jsx(Navbar, {});
|
|
67
|
+
$[9] = t3;
|
|
68
|
+
} else t3 = $[9];
|
|
69
|
+
let t4;
|
|
70
|
+
if ($[10] !== children) {
|
|
71
|
+
t4 = /* @__PURE__ */ jsxs("div", {
|
|
92
72
|
className: "bg-background flex h-screen flex-col overflow-hidden",
|
|
93
|
-
children: [
|
|
73
|
+
children: [t3, children]
|
|
94
74
|
});
|
|
95
|
-
$[
|
|
96
|
-
$[
|
|
97
|
-
} else
|
|
98
|
-
return
|
|
75
|
+
$[10] = children;
|
|
76
|
+
$[11] = t4;
|
|
77
|
+
} else t4 = $[11];
|
|
78
|
+
return t4;
|
|
99
79
|
};
|
|
100
80
|
|
|
101
81
|
//#endregion
|
|
@@ -30,15 +30,16 @@ function formatReason(reason, direction) {
|
|
|
30
30
|
case "block-definition-missing-in-source": return `Block type "${reason.blockId}" exists in ${targetLabel} but not in ${sourceLabel}.`;
|
|
31
31
|
case "block-definition-missing-in-target": return `Block type "${reason.blockId}" exists in ${sourceLabel} but not in ${targetLabel}. ${remedy}`;
|
|
32
32
|
case "block-definition-schema-mismatch": return `Block type "${reason.blockId}" has a different "${reason.field}" between envs. Sync block definitions and try again.`;
|
|
33
|
+
case "layout-kind-mismatch": return `Layout "${reason.layoutId}" has a different kind between environments. Sync layout definitions and try again.`;
|
|
33
34
|
case "layout-missing-in-source": return `Layout "${reason.layoutId}" exists in ${targetLabel} but not in ${sourceLabel}.`;
|
|
34
35
|
case "layout-missing-in-target": return `Layout "${reason.layoutId}" exists in ${sourceLabel} but not in ${targetLabel}. ${remedy}`;
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
const EnvironmentMenu = () => {
|
|
38
39
|
const $ = c(84);
|
|
39
|
-
if ($[0] !== "
|
|
40
|
+
if ($[0] !== "5eec2ee2385ce7d4417564ed3e8ad71e1d521ff3c557dea4a4ca42288fb12d99") {
|
|
40
41
|
for (let $i = 0; $i < 84; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
41
|
-
$[0] = "
|
|
42
|
+
$[0] = "5eec2ee2385ce7d4417564ed3e8ad71e1d521ff3c557dea4a4ca42288fb12d99";
|
|
42
43
|
}
|
|
43
44
|
const [open, setOpen] = React.useState(false);
|
|
44
45
|
const [pendingDirection, setPendingDirection] = React.useState(null);
|