camox 0.38.0 → 0.40.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.
@@ -1,8 +1,8 @@
1
1
  import { AuthContext, useAuthActions } from "../../lib/auth.js";
2
2
  import { projectQueries } from "../../lib/queries.js";
3
+ import { identifyProject, identifyUser } from "../../lib/telemetry-client.js";
3
4
  import { useApplyTheme, useThemeActions } from "../studio/useTheme.js";
4
5
  import { useNavbarActions } from "../studio/components/Navbar.js";
5
- import { identifyProject, identifyUser } from "../../lib/telemetry-client.js";
6
6
  import { usePreviewPagesActions } from "../preview/CamoxPreview.js";
7
7
  import { useProjectRoom } from "../../lib/use-project-room.js";
8
8
  import { CommandPalette, useCommandPaletteActions } from "./components/CommandPalette.js";
@@ -1,8 +1,8 @@
1
1
  import { Navigate, useLocation } from "../navigation/navigation.js";
2
2
  import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
3
3
  import { STUDIO_BASE_PATH } from "./routes.js";
4
- import { Navbar } from "./components/Navbar.js";
5
4
  import { trackClientEvent } from "../../lib/telemetry-client.js";
5
+ import { Navbar } from "./components/Navbar.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import * as React from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -13,9 +13,9 @@ import { Skeleton } from "@camox/ui/skeleton";
13
13
  //#region src/features/studio/components/ProjectMenu.tsx
14
14
  const Favicon = (t0) => {
15
15
  const $ = c(19);
16
- if ($[0] !== "d995cbe0a8e25c463e5078777395b1432b84ff5ecc4a4a3cc0e7e416badd244d") {
16
+ if ($[0] !== "da1b045f11b7e5155c87b753677133884f53ac964944786d14b5c4f7155ce7f7") {
17
17
  for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
18
- $[0] = "d995cbe0a8e25c463e5078777395b1432b84ff5ecc4a4a3cc0e7e416badd244d";
18
+ $[0] = "da1b045f11b7e5155c87b753677133884f53ac964944786d14b5c4f7155ce7f7";
19
19
  }
20
20
  const { size: t1 } = t0;
21
21
  const size = t1 === void 0 ? 16 : t1;
@@ -113,9 +113,9 @@ const Favicon = (t0) => {
113
113
  };
114
114
  const ProjectMenu = () => {
115
115
  const $ = c(41);
116
- if ($[0] !== "d995cbe0a8e25c463e5078777395b1432b84ff5ecc4a4a3cc0e7e416badd244d") {
116
+ if ($[0] !== "da1b045f11b7e5155c87b753677133884f53ac964944786d14b5c4f7155ce7f7") {
117
117
  for (let $i = 0; $i < 41; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
118
- $[0] = "d995cbe0a8e25c463e5078777395b1432b84ff5ecc4a4a3cc0e7e416badd244d";
118
+ $[0] = "da1b045f11b7e5155c87b753677133884f53ac964944786d14b5c4f7155ce7f7";
119
119
  }
120
120
  const authCtx = React.useContext(AuthContext);
121
121
  let t0;
@@ -1,18 +1,22 @@
1
+ import { useLocation, useNavigate } from "../../navigation/navigation.js";
1
2
  import { useAuthContext, useAuthState } from "../../../lib/auth.js";
3
+ import { STUDIO_BASE_PATH } from "../routes.js";
4
+ import { previewStore } from "../../preview/previewStore.js";
2
5
  import { useApplyTheme } from "../useTheme.js";
3
6
  import { c } from "react/compiler-runtime";
4
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useSelector } from "@xstate/store-react";
5
9
  import { Button } from "@camox/ui/button";
6
- import { Check, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
10
+ import { Check, EyeOff, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
7
11
  import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
8
12
  import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
9
13
 
10
14
  //#region src/features/studio/components/UserButton.tsx
11
15
  const UserButton = () => {
12
16
  const $ = c(5);
13
- if ($[0] !== "12e7d1da288408dfd3abde7ab7d46542026c286c39994da53885abf3ac49204c") {
17
+ if ($[0] !== "a09d40e74ed3a5b0583d8899c9b1d3c569af18304db9c6f598775bf2c16e2608") {
14
18
  for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
15
- $[0] = "12e7d1da288408dfd3abde7ab7d46542026c286c39994da53885abf3ac49204c";
19
+ $[0] = "a09d40e74ed3a5b0583d8899c9b1d3c569af18304db9c6f598775bf2c16e2608";
16
20
  }
17
21
  const { isAuthenticated, isLoading } = useAuthState();
18
22
  const { theme, setTheme } = useApplyTheme();
@@ -44,6 +48,15 @@ function AuthenticatedUserButton({ theme, setTheme }) {
44
48
  const authCtx = useAuthContext();
45
49
  const { data: session } = authCtx.authClient.useSession();
46
50
  const authenticationUrl = authCtx.authenticationUrl;
51
+ const isEditMode = useSelector(previewStore, (state) => state.context.isEditMode);
52
+ const { pathname } = useLocation();
53
+ const navigate = useNavigate();
54
+ const isPreviewPage = pathname !== STUDIO_BASE_PATH && !pathname.startsWith(`${STUDIO_BASE_PATH}/`);
55
+ const hideCamoxUi = () => {
56
+ previewStore.send({ type: "hideToolbar" });
57
+ if (isPreviewPage) return;
58
+ navigate({ to: "/" });
59
+ };
47
60
  const userName = session?.user?.name || "User";
48
61
  const userEmail = session?.user?.email;
49
62
  const userImage = session?.user?.image;
@@ -118,6 +131,11 @@ function AuthenticatedUserButton({ theme, setTheme }) {
118
131
  })
119
132
  ]
120
133
  })] }),
134
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
135
+ disabled: isPreviewPage && isEditMode,
136
+ onClick: hideCamoxUi,
137
+ children: [/* @__PURE__ */ jsx(EyeOff, {}), /* @__PURE__ */ jsx("span", { children: "Hide Camox UI" })]
138
+ }),
121
139
  /* @__PURE__ */ jsxs(DropdownMenuItem, {
122
140
  onClick: () => void authCtx.authClient.signOut(),
123
141
  children: [/* @__PURE__ */ jsx(LogOut, {}), /* @__PURE__ */ jsx("span", { children: "Sign out" })]
@@ -0,0 +1,52 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+
5
+ //#region src/features/vite/auth.ts
6
+ const AUTH_DIR = path.join(os.homedir(), ".camox");
7
+ const AUTH_FILE = path.join(AUTH_DIR, "auth.json");
8
+ function normalizeUrl(url) {
9
+ return url.replace(/\/+$/, "");
10
+ }
11
+ function readAllTokens() {
12
+ try {
13
+ return JSON.parse(fs.readFileSync(AUTH_FILE, "utf-8"));
14
+ } catch {
15
+ return {};
16
+ }
17
+ }
18
+ function writeAllTokens(tokens) {
19
+ fs.mkdirSync(AUTH_DIR, { recursive: true });
20
+ fs.writeFileSync(AUTH_FILE, JSON.stringify(tokens, null, 2), { mode: 384 });
21
+ }
22
+ function readAuthTokenForUrl(authenticationUrl) {
23
+ const entry = readAllTokens()[normalizeUrl(authenticationUrl)];
24
+ if (entry?.token && entry?.name && typeof entry.email === "string") return entry;
25
+ return null;
26
+ }
27
+ function writeAuthTokenForUrl(authenticationUrl, token) {
28
+ const tokens = readAllTokens();
29
+ tokens[normalizeUrl(authenticationUrl)] = token;
30
+ writeAllTokens(tokens);
31
+ }
32
+ async function verifyOneTimeToken(apiUrl, token) {
33
+ const response = await fetch(`${normalizeUrl(apiUrl)}/api/auth/one-time-token/verify`, {
34
+ method: "POST",
35
+ headers: { "Content-Type": "application/json" },
36
+ body: JSON.stringify({ token })
37
+ });
38
+ if (!response.ok) throw new Error(`OTT verification failed: ${response.status}`);
39
+ const data = await response.json();
40
+ const user = data.user;
41
+ if (!user?.name) throw new Error("No user info in verification response");
42
+ const sessionToken = data.session?.token;
43
+ if (!sessionToken) throw new Error("No session token in verification response");
44
+ return {
45
+ name: user.name,
46
+ email: user.email ?? "",
47
+ token: sessionToken
48
+ };
49
+ }
50
+
51
+ //#endregion
52
+ export { readAuthTokenForUrl, verifyOneTimeToken, writeAuthTokenForUrl };
@@ -1,4 +1,4 @@
1
- import { verifyOneTimeToken, writeAuthTokenForUrl } from "@camox/cli/auth";
1
+ import { verifyOneTimeToken, writeAuthTokenForUrl } from "./auth.js";
2
2
  import { randomBytes } from "node:crypto";
3
3
 
4
4
  //#region src/features/vite/devAuthentication.ts
@@ -1,4 +1,5 @@
1
1
  import { generateAppFile, watchAppFile } from "./appGeneration.js";
2
+ import { readAuthTokenForUrl } from "./auth.js";
2
3
  import { watchNewBlockFiles } from "./blockBoilerplate.js";
3
4
  import { installDevAuthenticationMiddleware } from "./devAuthentication.js";
4
5
  import { syncDefinitions, syncDefinitionsToApi } from "./definitionsSync.js";
@@ -7,7 +8,6 @@ import { installRuntimeNitroRoutes, loadRuntimeDevModule, resolveRuntimeDevId }
7
8
  import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
9
  import { dirname, join, resolve } from "node:path";
9
10
  import { fileURLToPath } from "node:url";
10
- import { readAuthTokenForUrl } from "@camox/cli/auth";
11
11
  import { createServer } from "vite-plus";
12
12
 
13
13
  //#region src/features/vite/vite.ts
@@ -169,7 +169,6 @@ function camox(options) {
169
169
  "camox > @shikijs/themes/github-light",
170
170
  "camox > @sinclair/typebox",
171
171
  "camox > @takumi-rs/image-response",
172
- "camox > @tanstack/ai-react",
173
172
  "camox > @tanstack/react-form",
174
173
  "camox > @xstate/store-react",
175
174
  "camox > better-auth > @better-auth/core/env",
@@ -183,9 +182,6 @@ function camox(options) {
183
182
  "camox > lexical",
184
183
  "camox > lucide-react",
185
184
  "camox > posthog-js",
186
- "camox > streamdown",
187
- "camox > streamdown > hast-util-to-jsx-runtime",
188
- "camox > streamdown > hast-util-to-jsx-runtime > style-to-js",
189
185
  "camox > @tanstack/react-query-devtools/production",
190
186
  "camox > partysocket/react"
191
187
  ] }