camox 0.32.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AuthGate.js +5 -4
- package/dist/core/createBlock.d.ts +1 -1
- package/dist/core/createBlock.js +88 -108
- package/dist/core/hooks/useIsEditable.js +6 -10
- package/dist/core/lib/fieldTypes.js +10 -219
- package/dist/features/agent-chat/components/AgentChatSidebar.js +172 -0
- package/dist/features/agent-chat/components/AgentChatThread.js +14 -15
- package/dist/features/preview/CamoxPreview.js +137 -729
- package/dist/features/preview/components/{AddBlockSheet.js → AddBlockSidebar.js} +121 -131
- package/dist/features/preview/components/AssetFieldEditor.js +107 -82
- package/dist/features/preview/components/AssetLightbox.js +14 -13
- package/dist/features/preview/components/AssetPickerModal.js +277 -0
- package/dist/features/preview/components/BlockActionsPopover.js +18 -24
- package/dist/features/preview/components/CreatePageModal.js +6 -6
- package/dist/features/preview/components/FieldToolbar.js +64 -127
- package/dist/features/preview/components/ItemFieldsEditor.js +98 -125
- package/dist/features/preview/components/LeftSidebar.js +64 -0
- package/dist/features/preview/components/LinkFieldEditor.js +1 -1
- package/dist/features/preview/components/MultipleAssetFieldEditor.js +94 -56
- package/dist/features/preview/components/OverlayTracker.js +15 -15
- package/dist/features/preview/components/Overlays.js +12 -12
- package/dist/features/preview/components/PageEditorSidebar.js +563 -0
- package/dist/features/preview/components/PageInfoSidebar.js +1453 -0
- package/dist/features/preview/components/PageNavigatorSidebar.js +590 -0
- package/dist/features/preview/components/PagePicker.js +3 -3
- package/dist/features/preview/components/PageStatusBadge.js +1 -1
- package/dist/features/preview/components/PageTree.js +204 -564
- package/dist/features/preview/components/PreviewPanel.js +123 -158
- package/dist/features/preview/components/PreviewToolbar.js +260 -256
- package/dist/features/preview/components/PublishDialog.js +2 -2
- package/dist/features/preview/components/RepeatableItemsList.js +2 -2
- package/dist/features/preview/components/RightSidebar.js +109 -0
- package/dist/features/preview/components/UnlinkAssetButton.js +2 -2
- package/dist/features/preview/components/useRepeatableItemActions.js +3 -138
- package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
- package/dist/features/preview/previewQueryFns.js +23 -0
- package/dist/features/preview/previewStore.js +46 -63
- package/dist/features/provider/CamoxProvider.js +255 -70
- package/dist/features/provider/useAdminShortcuts.js +5 -48
- package/dist/features/routes/pageRoute.js +1 -1
- package/dist/features/studio/CamoxStudio.js +6 -5
- package/dist/features/studio/components/EnvironmentMenu.js +2 -2
- package/dist/features/studio/components/Navbar.js +53 -71
- package/dist/features/studio/components/ProjectMenu.js +1 -1
- package/dist/features/studio/components/UserButton.js +1 -1
- package/dist/features/studio/routes.js +7 -0
- package/dist/features/studio/useTheme.js +67 -33
- package/dist/features/vite/routeGeneration.js +68 -66
- package/dist/hooks/use-file-upload.js +4 -2
- package/dist/lib/api-client.js +6 -3
- package/dist/lib/auth.js +29 -25
- package/dist/lib/queries.js +6 -4
- package/dist/lib/utils.js +1 -1
- package/dist/studio-overlays.css +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/dist/features/agent-chat/components/AgentChatSheet.js +0 -207
- package/dist/features/preview/components/AssetPickerGrid.js +0 -236
- package/dist/features/preview/components/PageContentSheet.js +0 -608
- package/dist/features/preview/components/PageMetadataModal.js +0 -908
- package/dist/features/preview/components/PreviewSideSheet.js +0 -76
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { useIsPreviewSheetOpen } from "../../preview/components/PreviewSideSheet.js";
|
|
2
1
|
import { actionsStore } from "../../provider/actionsStore.js";
|
|
3
2
|
import { useProjectSlug } from "../../../lib/auth.js";
|
|
4
3
|
import { pageQueries, projectQueries } from "../../../lib/queries.js";
|
|
5
4
|
import { cn } from "../../../lib/utils.js";
|
|
5
|
+
import { STUDIO_CONTENT_PATH } from "../routes.js";
|
|
6
6
|
import { studioStore } from "../studioStore.js";
|
|
7
7
|
import { EnvironmentMenu } from "./EnvironmentMenu.js";
|
|
8
8
|
import { ProjectMenu } from "./ProjectMenu.js";
|
|
9
9
|
import { UserButton } from "./UserButton.js";
|
|
10
10
|
import { c } from "react/compiler-runtime";
|
|
11
|
-
import { Kbd } from "@camox/ui/kbd";
|
|
12
11
|
import { useQuery } from "@tanstack/react-query";
|
|
13
12
|
import { Link, useLocation, useNavigate } from "@tanstack/react-router";
|
|
14
13
|
import * as React from "react";
|
|
14
|
+
import { Kbd } from "@camox/ui/kbd";
|
|
15
15
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
import { Button } from "@camox/ui/button";
|
|
17
17
|
import { Database, Globe, SearchIcon } from "lucide-react";
|
|
@@ -24,7 +24,7 @@ const links = [{
|
|
|
24
24
|
icon: "Globe",
|
|
25
25
|
aliases: ["Preview", "Website"]
|
|
26
26
|
}, {
|
|
27
|
-
to:
|
|
27
|
+
to: STUDIO_CONTENT_PATH,
|
|
28
28
|
title: "Content",
|
|
29
29
|
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Database, { className: "h-4 w-4" }), "Content"] }),
|
|
30
30
|
icon: "FileText",
|
|
@@ -35,10 +35,10 @@ const links = [{
|
|
|
35
35
|
]
|
|
36
36
|
}];
|
|
37
37
|
const Navbar = () => {
|
|
38
|
-
const $ = c(
|
|
39
|
-
if ($[0] !== "
|
|
40
|
-
for (let $i = 0; $i <
|
|
41
|
-
$[0] = "
|
|
38
|
+
const $ = c(19);
|
|
39
|
+
if ($[0] !== "eea0214bb845c9520caf17dd35f6ab89aaf76f8bfb610142be4d515eefd136f8") {
|
|
40
|
+
for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
41
|
+
$[0] = "eea0214bb845c9520caf17dd35f6ab89aaf76f8bfb610142be4d515eefd136f8";
|
|
42
42
|
}
|
|
43
43
|
const projectSlug = useProjectSlug();
|
|
44
44
|
let t0;
|
|
@@ -68,75 +68,62 @@ const Navbar = () => {
|
|
|
68
68
|
const { data: pages } = useQuery(t3);
|
|
69
69
|
const isMac = navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
70
70
|
const { pathname } = useLocation();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
t5 = cn("absolute top-0 left-0 w-full h-[calc(100%+2px)] bg-black/66 transition-opacity z-10 will-change-auto pointer-events-none", t4);
|
|
75
|
-
$[8] = t4;
|
|
76
|
-
$[9] = t5;
|
|
77
|
-
} else t5 = $[9];
|
|
78
|
-
let t6;
|
|
79
|
-
if ($[10] !== t5) {
|
|
80
|
-
t6 = /* @__PURE__ */ jsx("div", { className: t5 });
|
|
81
|
-
$[10] = t5;
|
|
82
|
-
$[11] = t6;
|
|
83
|
-
} else t6 = $[11];
|
|
84
|
-
let t7;
|
|
85
|
-
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
86
|
-
t7 = /* @__PURE__ */ jsxs("div", {
|
|
71
|
+
let t4;
|
|
72
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
73
|
+
t4 = /* @__PURE__ */ jsxs("div", {
|
|
87
74
|
className: "flew-row flex gap-1",
|
|
88
75
|
children: [/* @__PURE__ */ jsx(ProjectMenu, {}), /* @__PURE__ */ jsx(EnvironmentMenu, {})]
|
|
89
76
|
});
|
|
90
|
-
$[
|
|
91
|
-
} else
|
|
92
|
-
let
|
|
93
|
-
if ($[
|
|
94
|
-
|
|
77
|
+
$[8] = t4;
|
|
78
|
+
} else t4 = $[8];
|
|
79
|
+
let t5;
|
|
80
|
+
if ($[9] !== pages || $[10] !== pathname) {
|
|
81
|
+
t5 = links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Link, {
|
|
95
82
|
to: link.to,
|
|
96
83
|
className: cn("flex gap-2 items-center rounded-md px-4 py-2 text-sm font-medium", "hover:bg-accent hover:text-accent-foreground outline-none transition-[color,box-shadow] focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:outline-1", pages?.some((page) => page.fullPath === pathname) && index === 0 ? "bg-accent hover:bg-accent text-accent-foreground" : "text-muted-foreground"),
|
|
97
84
|
activeProps: { className: "bg-accent hover:bg-accent text-accent-foreground!" },
|
|
98
85
|
children: link.children
|
|
99
86
|
}) }, link.to));
|
|
100
|
-
$[
|
|
101
|
-
$[
|
|
102
|
-
$[
|
|
103
|
-
} else
|
|
104
|
-
let
|
|
105
|
-
if ($[
|
|
106
|
-
|
|
87
|
+
$[9] = pages;
|
|
88
|
+
$[10] = pathname;
|
|
89
|
+
$[11] = t5;
|
|
90
|
+
} else t5 = $[11];
|
|
91
|
+
let t6;
|
|
92
|
+
if ($[12] !== t5) {
|
|
93
|
+
t6 = /* @__PURE__ */ jsxs("div", {
|
|
107
94
|
className: "flex flex-row gap-2",
|
|
108
|
-
children: [
|
|
95
|
+
children: [t4, /* @__PURE__ */ jsx("ul", {
|
|
109
96
|
className: "flex items-center gap-1",
|
|
110
|
-
children:
|
|
97
|
+
children: t5
|
|
111
98
|
})]
|
|
112
99
|
});
|
|
113
|
-
$[
|
|
114
|
-
$[
|
|
115
|
-
} else
|
|
116
|
-
let
|
|
117
|
-
let
|
|
118
|
-
if ($[
|
|
119
|
-
|
|
120
|
-
|
|
100
|
+
$[12] = t5;
|
|
101
|
+
$[13] = t6;
|
|
102
|
+
} else t6 = $[13];
|
|
103
|
+
let t7;
|
|
104
|
+
let t8;
|
|
105
|
+
if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
|
|
106
|
+
t7 = /* @__PURE__ */ jsx(SearchIcon, { className: "text-muted-foreground size-4" });
|
|
107
|
+
t8 = /* @__PURE__ */ jsx("span", {
|
|
121
108
|
className: "text-muted-foreground",
|
|
122
109
|
children: "Quick find"
|
|
123
110
|
});
|
|
124
|
-
$[
|
|
125
|
-
$[
|
|
111
|
+
$[14] = t7;
|
|
112
|
+
$[15] = t8;
|
|
126
113
|
} else {
|
|
127
|
-
|
|
128
|
-
|
|
114
|
+
t7 = $[14];
|
|
115
|
+
t8 = $[15];
|
|
129
116
|
}
|
|
130
|
-
let
|
|
131
|
-
if ($[
|
|
132
|
-
|
|
117
|
+
let t9;
|
|
118
|
+
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
|
119
|
+
t9 = /* @__PURE__ */ jsxs("div", {
|
|
133
120
|
className: "flex items-center gap-2",
|
|
134
121
|
children: [/* @__PURE__ */ jsxs(Button, {
|
|
135
122
|
variant: "outline",
|
|
136
123
|
onClick: _temp,
|
|
137
124
|
children: [
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
t7,
|
|
126
|
+
t8,
|
|
140
127
|
/* @__PURE__ */ jsxs(Kbd, {
|
|
141
128
|
className: "ml-4",
|
|
142
129
|
children: [isMac ? "⌘" : "Ctrl", " K"]
|
|
@@ -144,29 +131,24 @@ const Navbar = () => {
|
|
|
144
131
|
]
|
|
145
132
|
}), /* @__PURE__ */ jsx(UserButton, {})]
|
|
146
133
|
});
|
|
147
|
-
$[
|
|
148
|
-
} else
|
|
149
|
-
let
|
|
150
|
-
if ($[
|
|
151
|
-
|
|
134
|
+
$[16] = t9;
|
|
135
|
+
} else t9 = $[16];
|
|
136
|
+
let t10;
|
|
137
|
+
if ($[17] !== t6) {
|
|
138
|
+
t10 = /* @__PURE__ */ jsxs("nav", {
|
|
152
139
|
className: "relative flex items-center justify-between gap-4 border-b-2 bg-transparent px-2 py-2",
|
|
153
|
-
children: [
|
|
154
|
-
t6,
|
|
155
|
-
t9,
|
|
156
|
-
t12
|
|
157
|
-
]
|
|
140
|
+
children: [t6, t9]
|
|
158
141
|
});
|
|
159
|
-
$[
|
|
160
|
-
$[
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return t13;
|
|
142
|
+
$[17] = t6;
|
|
143
|
+
$[18] = t10;
|
|
144
|
+
} else t10 = $[18];
|
|
145
|
+
return t10;
|
|
164
146
|
};
|
|
165
147
|
function useNavbarActions() {
|
|
166
148
|
const $ = c(4);
|
|
167
|
-
if ($[0] !== "
|
|
149
|
+
if ($[0] !== "eea0214bb845c9520caf17dd35f6ab89aaf76f8bfb610142be4d515eefd136f8") {
|
|
168
150
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
169
|
-
$[0] = "
|
|
151
|
+
$[0] = "eea0214bb845c9520caf17dd35f6ab89aaf76f8bfb610142be4d515eefd136f8";
|
|
170
152
|
}
|
|
171
153
|
const navigate = useNavigate();
|
|
172
154
|
let t0;
|
|
@@ -6,8 +6,8 @@ import { Link } from "@tanstack/react-router";
|
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Button } from "@camox/ui/button";
|
|
9
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
|
|
10
9
|
import { ChevronDown, Globe, Info, Settings, Users } from "lucide-react";
|
|
10
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
|
|
11
11
|
import { Skeleton } from "@camox/ui/skeleton";
|
|
12
12
|
|
|
13
13
|
//#region src/features/studio/components/ProjectMenu.tsx
|
|
@@ -3,8 +3,8 @@ import { useApplyTheme } from "../useTheme.js";
|
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { Button } from "@camox/ui/button";
|
|
6
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
|
|
7
6
|
import { Check, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
|
|
7
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
|
|
8
8
|
import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
|
|
9
9
|
|
|
10
10
|
//#region src/features/studio/components/UserButton.tsx
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/features/studio/routes.ts
|
|
2
|
+
const STUDIO_ROUTE_SEGMENT = "camox";
|
|
3
|
+
const STUDIO_BASE_PATH = `/${STUDIO_ROUTE_SEGMENT}`;
|
|
4
|
+
const STUDIO_CONTENT_PATH = `${STUDIO_BASE_PATH}/content`;
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
export { STUDIO_BASE_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT };
|
|
@@ -3,6 +3,7 @@ import { c } from "react/compiler-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/features/studio/useTheme.ts
|
|
6
|
+
let activeThemeOwnerCount = 0;
|
|
6
7
|
function readStoredTheme() {
|
|
7
8
|
if (typeof window === "undefined") return "system";
|
|
8
9
|
return localStorage.getItem("theme") || "system";
|
|
@@ -15,9 +16,9 @@ function readStoredTheme() {
|
|
|
15
16
|
*/
|
|
16
17
|
function useThemeValue() {
|
|
17
18
|
const $ = c(3);
|
|
18
|
-
if ($[0] !== "
|
|
19
|
+
if ($[0] !== "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f") {
|
|
19
20
|
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
20
|
-
$[0] = "
|
|
21
|
+
$[0] = "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f";
|
|
21
22
|
}
|
|
22
23
|
const [theme] = React.useState(readStoredTheme);
|
|
23
24
|
let t0;
|
|
@@ -34,34 +35,70 @@ function useThemeValue() {
|
|
|
34
35
|
* never from contexts that share `<html>` with the user's site.
|
|
35
36
|
*/
|
|
36
37
|
function useApplyTheme() {
|
|
37
|
-
const $ = c(
|
|
38
|
-
if ($[0] !== "
|
|
39
|
-
for (let $i = 0; $i <
|
|
40
|
-
$[0] = "
|
|
38
|
+
const $ = c(10);
|
|
39
|
+
if ($[0] !== "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f") {
|
|
40
|
+
for (let $i = 0; $i < 10; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
41
|
+
$[0] = "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f";
|
|
41
42
|
}
|
|
42
43
|
const [theme, setTheme] = React.useState(readStoredTheme);
|
|
43
|
-
const
|
|
44
|
+
const [resolvedTheme, setResolvedTheme] = React.useState("light");
|
|
44
45
|
let t0;
|
|
45
46
|
let t1;
|
|
46
47
|
if ($[1] !== theme) {
|
|
47
48
|
t0 = () => {
|
|
48
|
-
const
|
|
49
|
-
|
|
49
|
+
const root = window.document.documentElement;
|
|
50
|
+
const body = window.document.body;
|
|
51
|
+
activeThemeOwnerCount = activeThemeOwnerCount + 1;
|
|
52
|
+
const applyTheme = (themeToApply) => {
|
|
53
|
+
setResolvedTheme(themeToApply);
|
|
54
|
+
root.classList.remove("light", "dark");
|
|
55
|
+
root.classList.add(themeToApply);
|
|
56
|
+
root.dataset.camoxStudioTheme = themeToApply;
|
|
57
|
+
body.classList.remove("light", "dark");
|
|
58
|
+
body.classList.add("camox-studio-theme", themeToApply);
|
|
59
|
+
body.dataset.camoxStudioTheme = themeToApply;
|
|
60
|
+
};
|
|
61
|
+
const resolveTheme = () => {
|
|
62
|
+
if (theme !== "system") return theme;
|
|
63
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
64
|
+
};
|
|
65
|
+
applyTheme(resolveTheme());
|
|
66
|
+
const observer = new MutationObserver(() => {
|
|
67
|
+
const themeToApply_0 = resolveTheme();
|
|
68
|
+
if (root.classList.contains(themeToApply_0) && body.classList.contains(themeToApply_0)) return;
|
|
69
|
+
applyTheme(themeToApply_0);
|
|
70
|
+
});
|
|
71
|
+
observer.observe(root, {
|
|
72
|
+
attributes: true,
|
|
73
|
+
attributeFilter: ["class"]
|
|
74
|
+
});
|
|
75
|
+
observer.observe(body, {
|
|
76
|
+
attributes: true,
|
|
77
|
+
attributeFilter: ["class"]
|
|
78
|
+
});
|
|
50
79
|
if (theme === "system") {
|
|
51
80
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
52
|
-
const updateSystemTheme = () =>
|
|
53
|
-
applyTheme(mediaQuery.matches ? "dark" : "light");
|
|
54
|
-
};
|
|
55
|
-
updateSystemTheme();
|
|
81
|
+
const updateSystemTheme = () => applyTheme(resolveTheme());
|
|
56
82
|
mediaQuery.addEventListener("change", updateSystemTheme);
|
|
57
83
|
return () => {
|
|
58
84
|
mediaQuery.removeEventListener("change", updateSystemTheme);
|
|
59
|
-
|
|
85
|
+
observer.disconnect();
|
|
86
|
+
activeThemeOwnerCount = activeThemeOwnerCount - 1;
|
|
87
|
+
if (activeThemeOwnerCount > 0) return;
|
|
88
|
+
root.classList.remove("light", "dark");
|
|
89
|
+
delete root.dataset.camoxStudioTheme;
|
|
90
|
+
body.classList.remove("camox-studio-theme", "light", "dark");
|
|
91
|
+
delete body.dataset.camoxStudioTheme;
|
|
60
92
|
};
|
|
61
93
|
}
|
|
62
|
-
root_0.classList.add(theme);
|
|
63
94
|
return () => {
|
|
64
|
-
|
|
95
|
+
observer.disconnect();
|
|
96
|
+
activeThemeOwnerCount = activeThemeOwnerCount - 1;
|
|
97
|
+
if (activeThemeOwnerCount > 0) return;
|
|
98
|
+
root.classList.remove("light", "dark");
|
|
99
|
+
delete root.dataset.camoxStudioTheme;
|
|
100
|
+
body.classList.remove("camox-studio-theme", "light", "dark");
|
|
101
|
+
delete body.dataset.camoxStudioTheme;
|
|
65
102
|
};
|
|
66
103
|
};
|
|
67
104
|
t1 = [theme];
|
|
@@ -89,26 +126,23 @@ function useApplyTheme() {
|
|
|
89
126
|
}
|
|
90
127
|
React.useEffect(t2, t3);
|
|
91
128
|
let t4;
|
|
92
|
-
if ($[7] !== theme) {
|
|
129
|
+
if ($[7] !== resolvedTheme || $[8] !== theme) {
|
|
93
130
|
t4 = {
|
|
94
131
|
theme,
|
|
132
|
+
resolvedTheme,
|
|
95
133
|
setTheme
|
|
96
134
|
};
|
|
97
|
-
$[7] =
|
|
98
|
-
$[8] =
|
|
99
|
-
|
|
135
|
+
$[7] = resolvedTheme;
|
|
136
|
+
$[8] = theme;
|
|
137
|
+
$[9] = t4;
|
|
138
|
+
} else t4 = $[9];
|
|
100
139
|
return t4;
|
|
101
140
|
}
|
|
102
|
-
function _temp(themeToApply) {
|
|
103
|
-
const root = window.document.documentElement;
|
|
104
|
-
root.classList.remove("light", "dark");
|
|
105
|
-
root.classList.add(themeToApply);
|
|
106
|
-
}
|
|
107
141
|
function useThemeActions() {
|
|
108
142
|
const $ = c(5);
|
|
109
|
-
if ($[0] !== "
|
|
143
|
+
if ($[0] !== "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f") {
|
|
110
144
|
for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
111
|
-
$[0] = "
|
|
145
|
+
$[0] = "da3935c3f496f05138d1e012522f8d34be97b470fa5c8f37185df49127eab10f";
|
|
112
146
|
}
|
|
113
147
|
const { theme, setTheme } = useApplyTheme();
|
|
114
148
|
let t0;
|
|
@@ -125,9 +159,9 @@ function useThemeActions() {
|
|
|
125
159
|
"Color mode"
|
|
126
160
|
],
|
|
127
161
|
groupLabel: "Studio",
|
|
128
|
-
checkIfAvailable:
|
|
162
|
+
checkIfAvailable: _temp,
|
|
129
163
|
hasChildren: true,
|
|
130
|
-
execute:
|
|
164
|
+
execute: _temp2
|
|
131
165
|
},
|
|
132
166
|
{
|
|
133
167
|
id: "switch-to-light-theme",
|
|
@@ -164,7 +198,7 @@ function useThemeActions() {
|
|
|
164
198
|
return () => {
|
|
165
199
|
actionsStore.send({
|
|
166
200
|
type: "unregisterManyActions",
|
|
167
|
-
ids: actions.map(
|
|
201
|
+
ids: actions.map(_temp3)
|
|
168
202
|
});
|
|
169
203
|
};
|
|
170
204
|
};
|
|
@@ -179,11 +213,11 @@ function useThemeActions() {
|
|
|
179
213
|
}
|
|
180
214
|
React.useEffect(t0, t1);
|
|
181
215
|
}
|
|
182
|
-
function
|
|
216
|
+
function _temp3(a) {
|
|
183
217
|
return a.id;
|
|
184
218
|
}
|
|
185
|
-
function
|
|
186
|
-
function
|
|
219
|
+
function _temp2() {}
|
|
220
|
+
function _temp() {
|
|
187
221
|
return true;
|
|
188
222
|
}
|
|
189
223
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { STUDIO_ROUTE_SEGMENT } from "../studio/routes.js";
|
|
1
2
|
import { writeIfChanged } from "./utils.js";
|
|
2
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { relative, resolve } from "node:path";
|
|
4
5
|
|
|
5
6
|
//#region src/features/vite/routeGeneration.ts
|
|
@@ -15,25 +16,7 @@ const HEADER = `/* =============================================================
|
|
|
15
16
|
// @ts-nocheck
|
|
16
17
|
|
|
17
18
|
`;
|
|
18
|
-
function
|
|
19
|
-
return HEADER + `import { Outlet, createFileRoute } from "@tanstack/react-router";
|
|
20
|
-
import { CamoxProvider } from "camox/CamoxProvider";
|
|
21
|
-
import { camoxApp } from "@/camox/app";
|
|
22
|
-
|
|
23
|
-
export const Route = createFileRoute("/_camox")({
|
|
24
|
-
component: CamoxPathlessLayout,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
function CamoxPathlessLayout() {
|
|
28
|
-
return (
|
|
29
|
-
<CamoxProvider camoxApp={camoxApp} authenticationUrl="${authenticationUrl}" apiUrl={__CAMOX_API_URL__} projectSlug={__CAMOX_PROJECT_SLUG__} environmentName={__CAMOX_ENVIRONMENT_NAME__}>
|
|
30
|
-
<Outlet />
|
|
31
|
-
</CamoxProvider>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
`;
|
|
35
|
-
}
|
|
36
|
-
function generatePageRoute() {
|
|
19
|
+
function generatePageRoute(authenticationUrl) {
|
|
37
20
|
return HEADER + `import { createFileRoute } from "@tanstack/react-router";
|
|
38
21
|
import {
|
|
39
22
|
createMarkdownMiddleware,
|
|
@@ -41,21 +24,30 @@ import {
|
|
|
41
24
|
createPageHead,
|
|
42
25
|
PageRouteComponent,
|
|
43
26
|
} from "camox/_internal/pageRoute";
|
|
27
|
+
import { CamoxProvider } from "camox/CamoxProvider";
|
|
44
28
|
import { camoxApp } from "@/camox/app";
|
|
45
29
|
|
|
46
30
|
const markdownMiddleware = createMarkdownMiddleware(__CAMOX_API_URL__, __CAMOX_PROJECT_SLUG__, __CAMOX_ENVIRONMENT_NAME__);
|
|
47
31
|
const loader = createPageLoader(__CAMOX_API_URL__, __CAMOX_PROJECT_SLUG__, __CAMOX_ENVIRONMENT_NAME__);
|
|
48
32
|
const head = createPageHead(camoxApp);
|
|
49
33
|
|
|
50
|
-
export const Route = createFileRoute("/
|
|
34
|
+
export const Route = createFileRoute("/(camox)/(_preview)/$")({
|
|
51
35
|
server: {
|
|
52
36
|
middleware: [markdownMiddleware],
|
|
53
37
|
},
|
|
54
|
-
component:
|
|
38
|
+
component: RouteComponent,
|
|
55
39
|
notFoundComponent: () => <div>No Camox page on this path</div>,
|
|
56
40
|
loader,
|
|
57
41
|
head,
|
|
58
42
|
});
|
|
43
|
+
|
|
44
|
+
function RouteComponent() {
|
|
45
|
+
return (
|
|
46
|
+
<CamoxProvider camoxApp={camoxApp} authenticationUrl="${authenticationUrl}" apiUrl={__CAMOX_API_URL__} projectSlug={__CAMOX_PROJECT_SLUG__} environmentName={__CAMOX_ENVIRONMENT_NAME__}>
|
|
47
|
+
<PageRouteComponent />
|
|
48
|
+
</CamoxProvider>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
59
51
|
`;
|
|
60
52
|
}
|
|
61
53
|
function generateOgRoute() {
|
|
@@ -63,51 +55,40 @@ function generateOgRoute() {
|
|
|
63
55
|
import { createOgHandler } from "camox/_internal/ogRoute";
|
|
64
56
|
import { camoxApp } from "@/camox/app";
|
|
65
57
|
|
|
66
|
-
export const Route = createFileRoute("/
|
|
58
|
+
export const Route = createFileRoute("/(camox)/(_preview)/og")({
|
|
67
59
|
server: {
|
|
68
60
|
handlers: createOgHandler(camoxApp),
|
|
69
61
|
},
|
|
70
62
|
});
|
|
71
63
|
`;
|
|
72
64
|
}
|
|
73
|
-
function
|
|
74
|
-
return HEADER + `import { createFileRoute, redirect } from "@tanstack/react-router";
|
|
75
|
-
|
|
76
|
-
export const Route = createFileRoute("/_camox/cmx")({
|
|
77
|
-
component: RouteComponent,
|
|
78
|
-
loader: () => {
|
|
79
|
-
throw redirect({ to: "/cmx-studio" });
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
function RouteComponent() {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
`;
|
|
87
|
-
}
|
|
88
|
-
function generateCmxStudio() {
|
|
65
|
+
function generateCamoxStudio(authenticationUrl) {
|
|
89
66
|
return HEADER + `import { Outlet, createFileRoute } from "@tanstack/react-router";
|
|
67
|
+
import { CamoxProvider } from "camox/CamoxProvider";
|
|
90
68
|
import { CamoxStudio } from "camox/CamoxStudio";
|
|
69
|
+
import { camoxApp } from "@/camox/app";
|
|
91
70
|
|
|
92
|
-
export const Route = createFileRoute("/
|
|
71
|
+
export const Route = createFileRoute("/(camox)/(_studio)/${STUDIO_ROUTE_SEGMENT}")({
|
|
93
72
|
component: RouteComponent,
|
|
94
73
|
notFoundComponent: () => <div>Studio page not found</div>,
|
|
95
74
|
});
|
|
96
75
|
|
|
97
76
|
function RouteComponent() {
|
|
98
77
|
return (
|
|
99
|
-
<
|
|
100
|
-
<
|
|
101
|
-
|
|
78
|
+
<CamoxProvider camoxApp={camoxApp} authenticationUrl="${authenticationUrl}" apiUrl={__CAMOX_API_URL__} projectSlug={__CAMOX_PROJECT_SLUG__} environmentName={__CAMOX_ENVIRONMENT_NAME__}>
|
|
79
|
+
<CamoxStudio>
|
|
80
|
+
<Outlet />
|
|
81
|
+
</CamoxStudio>
|
|
82
|
+
</CamoxProvider>
|
|
102
83
|
);
|
|
103
84
|
}
|
|
104
85
|
`;
|
|
105
86
|
}
|
|
106
|
-
function
|
|
87
|
+
function generateCamoxStudioCatchAll() {
|
|
107
88
|
return HEADER + `import { Outlet, createFileRoute } from "@tanstack/react-router";
|
|
108
89
|
import { CamoxStudio } from "camox/CamoxStudio";
|
|
109
90
|
|
|
110
|
-
export const Route = createFileRoute("/
|
|
91
|
+
export const Route = createFileRoute("/(camox)/(_studio)/${STUDIO_ROUTE_SEGMENT}/$")({
|
|
111
92
|
component: RouteComponent,
|
|
112
93
|
notFoundComponent: () => <div>Studio page not found</div>,
|
|
113
94
|
});
|
|
@@ -121,11 +102,11 @@ function RouteComponent() {
|
|
|
121
102
|
}
|
|
122
103
|
`;
|
|
123
104
|
}
|
|
124
|
-
function
|
|
105
|
+
function generateCamoxStudioContent() {
|
|
125
106
|
return HEADER + `import { createFileRoute } from "@tanstack/react-router";
|
|
126
107
|
import { CamoxContent } from "camox/CamoxContent";
|
|
127
108
|
|
|
128
|
-
export const Route = createFileRoute("/
|
|
109
|
+
export const Route = createFileRoute("/(camox)/(_studio)/${STUDIO_ROUTE_SEGMENT}/content")({
|
|
129
110
|
component: RouteComponent,
|
|
130
111
|
});
|
|
131
112
|
|
|
@@ -135,40 +116,61 @@ function RouteComponent() {
|
|
|
135
116
|
`;
|
|
136
117
|
}
|
|
137
118
|
function getRouteFileEntries({ routesDir, authenticationUrl }) {
|
|
138
|
-
const
|
|
119
|
+
const groupDir = resolve(routesDir, "(camox)");
|
|
120
|
+
const previewDir = resolve(groupDir, "(_preview)");
|
|
121
|
+
const studioDir = resolve(groupDir, "(_studio)");
|
|
139
122
|
return [
|
|
140
123
|
{
|
|
141
|
-
path: resolve(
|
|
142
|
-
content:
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
path: resolve(camoxDir, "$.tsx"),
|
|
146
|
-
content: generatePageRoute()
|
|
124
|
+
path: resolve(previewDir, "$.tsx"),
|
|
125
|
+
content: generatePageRoute(authenticationUrl)
|
|
147
126
|
},
|
|
148
127
|
{
|
|
149
|
-
path: resolve(
|
|
128
|
+
path: resolve(previewDir, "og.tsx"),
|
|
150
129
|
content: generateOgRoute()
|
|
151
130
|
},
|
|
152
131
|
{
|
|
153
|
-
path: resolve(
|
|
154
|
-
content:
|
|
132
|
+
path: resolve(studioDir, `${STUDIO_ROUTE_SEGMENT}.tsx`),
|
|
133
|
+
content: generateCamoxStudio(authenticationUrl)
|
|
155
134
|
},
|
|
156
135
|
{
|
|
157
|
-
path: resolve(
|
|
158
|
-
content:
|
|
136
|
+
path: resolve(studioDir, `${STUDIO_ROUTE_SEGMENT}.$.tsx`),
|
|
137
|
+
content: generateCamoxStudioCatchAll()
|
|
159
138
|
},
|
|
160
139
|
{
|
|
161
|
-
path: resolve(
|
|
162
|
-
content:
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
path: resolve(camoxDir, "cmx-studio.content.tsx"),
|
|
166
|
-
content: generateCmxStudioContent()
|
|
140
|
+
path: resolve(studioDir, `${STUDIO_ROUTE_SEGMENT}.content.tsx`),
|
|
141
|
+
content: generateCamoxStudioContent()
|
|
167
142
|
}
|
|
168
143
|
];
|
|
169
144
|
}
|
|
145
|
+
function removeObsoleteRouteFiles(routesDir) {
|
|
146
|
+
const camoxDir = resolve(routesDir, "_camox");
|
|
147
|
+
const studioDir = resolve(routesDir, "(camox)", "(_studio)");
|
|
148
|
+
const obsoletePaths = [
|
|
149
|
+
resolve(routesDir, "_camox.tsx"),
|
|
150
|
+
resolve(camoxDir, "cmx.tsx"),
|
|
151
|
+
resolve(camoxDir, "$.tsx"),
|
|
152
|
+
resolve(camoxDir, "og.tsx"),
|
|
153
|
+
resolve(camoxDir, "cmx-studio.tsx"),
|
|
154
|
+
resolve(camoxDir, "cmx-studio.$.tsx"),
|
|
155
|
+
resolve(camoxDir, "cmx-studio.content.tsx"),
|
|
156
|
+
resolve(studioDir, "cmx.tsx"),
|
|
157
|
+
resolve(studioDir, "cmx-studio.tsx"),
|
|
158
|
+
resolve(studioDir, "cmx-studio.$.tsx"),
|
|
159
|
+
resolve(studioDir, "cmx-studio.content.tsx")
|
|
160
|
+
];
|
|
161
|
+
for (const filePath of obsoletePaths) try {
|
|
162
|
+
if (!readFileSync(filePath, "utf-8").startsWith(HEADER)) continue;
|
|
163
|
+
unlinkSync(filePath);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if (error.code === "ENOENT") continue;
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
170
169
|
function generateRouteFiles(options) {
|
|
171
|
-
|
|
170
|
+
const groupDir = resolve(options.routesDir, "(camox)");
|
|
171
|
+
mkdirSync(resolve(groupDir, "(_preview)"), { recursive: true });
|
|
172
|
+
mkdirSync(resolve(groupDir, "(_studio)"), { recursive: true });
|
|
173
|
+
removeObsoleteRouteFiles(options.routesDir);
|
|
172
174
|
for (const entry of getRouteFileEntries(options)) writeIfChanged(entry.path, entry.content);
|
|
173
175
|
}
|
|
174
176
|
function watchRouteFiles(options) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { trackClientEvent } from "../lib/telemetry-client.js";
|
|
4
3
|
import { getAuthCookieHeader } from "../lib/auth.js";
|
|
5
4
|
import { getApiUrl, getEnvironmentName } from "../lib/api-client.js";
|
|
5
|
+
import { trackClientEvent } from "../lib/telemetry-client.js";
|
|
6
6
|
import { useCallback, useRef, useState } from "react";
|
|
7
7
|
|
|
8
8
|
//#region src/hooks/use-file-upload.ts
|
|
@@ -40,8 +40,10 @@ function useFileUpload(options) {
|
|
|
40
40
|
formData.append("file", file);
|
|
41
41
|
formData.append("projectId", String(projectIdRef.current ?? 0));
|
|
42
42
|
const uploadUrl = `${apiUrl}/files/upload`;
|
|
43
|
+
const authCookieHeader = getAuthCookieHeader();
|
|
43
44
|
xhr.open("POST", uploadUrl);
|
|
44
|
-
xhr.
|
|
45
|
+
xhr.withCredentials = !authCookieHeader;
|
|
46
|
+
if (authCookieHeader) xhr.setRequestHeader("Better-Auth-Cookie", authCookieHeader);
|
|
45
47
|
const envName = getEnvironmentName();
|
|
46
48
|
if (envName) xhr.setRequestHeader("x-environment-name", envName);
|
|
47
49
|
xhr.send(formData);
|
package/dist/lib/api-client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAuthCookieHeader } from "./auth.js";
|
|
1
|
+
import { getAuthCookieHeader, getAuthRequestCredentials } from "./auth.js";
|
|
2
2
|
import { createORPCClient } from "@orpc/client";
|
|
3
3
|
import { RPCLink } from "@orpc/client/fetch";
|
|
4
4
|
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
|
|
@@ -18,10 +18,13 @@ function initApiClient(apiUrl, environmentName) {
|
|
|
18
18
|
url: `${apiUrl}/rpc`,
|
|
19
19
|
headers,
|
|
20
20
|
fetch: (request, init) => {
|
|
21
|
-
|
|
21
|
+
const authCookieHeader = getAuthCookieHeader();
|
|
22
|
+
if (request instanceof Request) {
|
|
23
|
+
if (authCookieHeader) request.headers.set("Better-Auth-Cookie", authCookieHeader);
|
|
24
|
+
}
|
|
22
25
|
return fetch(request, {
|
|
23
26
|
...init,
|
|
24
|
-
credentials:
|
|
27
|
+
credentials: getAuthRequestCredentials(authCookieHeader)
|
|
25
28
|
});
|
|
26
29
|
}
|
|
27
30
|
}));
|