camox 0.59.0 → 0.61.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/createApp.d.ts +8 -8
- package/dist/core/createBlock.d.ts +1 -2
- package/dist/core/createLayout.d.ts +10 -2
- package/dist/core/createLayout.js +1 -3
- package/dist/core/editing/BlockEditingRuntime.d.ts +1 -0
- package/dist/core/editing/CompleteBlockEditingRuntime.js +12 -9
- package/dist/core/editing/createEditableBlock.d.ts +4 -4
- package/dist/core/editing/createEditableBlock.js +20 -26
- package/dist/core/lib/artifactData.js +2 -2
- package/dist/core/lib/contentType.js +5 -4
- package/dist/features/preview/components/SelectionEditor.js +1 -1
- package/dist/features/renderer/RendererApp.js +187 -103
- package/dist/features/renderer/rendererHost.js +23 -16
- package/dist/features/renderer/studioConnection.js +8 -4
- package/dist/features/runtime/loopbackFetch.d.ts +8 -0
- package/dist/features/runtime/publicCache.d.ts +21 -0
- package/dist/features/runtime/publishingDraft.d.ts +4 -0
- package/dist/features/runtime/runtime.js +54 -3
- package/dist/features/runtime/worker.js +1 -4
- package/dist/features/runtime/workerRequest.d.ts +8 -0
- package/dist/features/runtime/workerRuntime.d.ts +5 -0
- package/dist/features/runtime/workerRuntime.js +6 -0
- package/dist/features/sdkBundle/buildSdkBundle.d.ts +40 -0
- package/dist/features/sdkBundle/buildSdkBundle.js +323 -0
- package/dist/features/sdkBundle/localSdkBundle.d.ts +44 -0
- package/dist/features/sdkBundle/localSdkBundle.js +162 -0
- package/dist/features/sdkBundle/sdkBundle.d.ts +3 -0
- package/dist/features/sdkBundle/sdkBundle.js +4 -0
- package/dist/features/sdkBundle/sdkBundleName.d.ts +59 -0
- package/dist/features/sdkBundle/sdkBundleName.js +164 -0
- package/dist/features/sdkBundle/specifiers.d.ts +34 -0
- package/dist/features/sdkBundle/specifiers.js +146 -0
- package/dist/features/settings/SocialProfilesSettings.js +284 -151
- package/dist/features/settings/useProjectMutation.js +6 -5
- package/dist/features/studio/FollowAgentProvider.js +71 -12
- package/dist/features/studio/components/ChatWidget.js +85 -43
- package/dist/features/studio/components/Patrol.js +311 -208
- package/dist/features/studio/components/Squareling.js +164 -66
- package/dist/features/studio/components/ThreadComposer.js +139 -69
- package/dist/features/studio/components/ThreadMessages.js +115 -45
- package/dist/features/studio/editorWhereContext.js +11 -0
- package/dist/features/studio/useEditorSelection.js +135 -0
- package/dist/features/vite/hostedChecks.js +1 -1
- package/dist/features/vite/runtimeDev.js +2 -1
- package/dist/features/vite/sdkBundleBuild.js +74 -0
- package/dist/features/vite/staticAssetHeaders.js +7 -4
- package/dist/features/vite/vite.d.ts +0 -2
- package/dist/features/vite/vite.js +33 -3
- package/dist/lib/auth.js +24 -58
- package/dist/lib/server-auth-cookie.js +12 -2
- package/dist/lib/stored-auth-cookies.js +76 -0
- package/dist/lib/use-thread.js +9 -5
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +17 -4
package/dist/lib/auth.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { actionsStore } from "../features/provider/actionsStore.js";
|
|
2
2
|
import { validatePreviewTarget } from "./preview-handoff.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buildClearServerAuthCookieHeader, buildServerAuthCookieHeader, getServerAuthCookieHeader, readServerAuthCookie } from "./server-auth-cookie.js";
|
|
4
|
+
import { getCookie, getSetCookie, parseSetCookieHeader, withCookieHeader } from "./stored-auth-cookies.js";
|
|
4
5
|
import { c } from "react/compiler-runtime";
|
|
5
6
|
import * as React from "react";
|
|
6
7
|
import { oneTimeTokenClient, organizationClient } from "better-auth/client/plugins";
|
|
@@ -9,60 +10,26 @@ import { createAuthClient } from "better-auth/react";
|
|
|
9
10
|
//#region src/lib/auth.ts
|
|
10
11
|
function writeServerAuthCookie(cookie) {
|
|
11
12
|
if (typeof document === "undefined") return;
|
|
12
|
-
const secure = window.location.protocol === "https:"
|
|
13
|
+
const secure = window.location.protocol === "https:";
|
|
13
14
|
if (!cookie) {
|
|
14
|
-
document.cookie = `${buildClearServerAuthCookieHeader()}${secure}`;
|
|
15
|
+
document.cookie = `${buildClearServerAuthCookieHeader()}${secure ? "; Secure" : ""}`;
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
|
-
document.cookie =
|
|
18
|
+
document.cookie = buildServerAuthCookieHeader(cookie, { secure });
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
function getSetCookie(header, prevCookie) {
|
|
34
|
-
const parsed = parseSetCookieHeader(header);
|
|
35
|
-
let toSetCookie = {};
|
|
36
|
-
parsed.forEach((cookie, key) => {
|
|
37
|
-
const expiresAt = cookie["expires"];
|
|
38
|
-
const maxAge = cookie["max-age"];
|
|
39
|
-
let expires = null;
|
|
40
|
-
if (expiresAt) expires = new Date(String(expiresAt));
|
|
41
|
-
else if (maxAge) expires = new Date(Date.now() + Number(maxAge) * 1e3);
|
|
42
|
-
toSetCookie[key] = {
|
|
43
|
-
value: cookie["value"],
|
|
44
|
-
expires: expires ? expires.toISOString() : null
|
|
45
|
-
};
|
|
46
|
-
});
|
|
47
|
-
if (prevCookie) try {
|
|
48
|
-
toSetCookie = {
|
|
49
|
-
...JSON.parse(prevCookie),
|
|
50
|
-
...toSetCookie
|
|
51
|
-
};
|
|
52
|
-
} catch {}
|
|
53
|
-
return JSON.stringify(toSetCookie);
|
|
54
|
-
}
|
|
55
|
-
function getCookie(cookie) {
|
|
56
|
-
let parsed = {};
|
|
57
|
-
try {
|
|
58
|
-
parsed = JSON.parse(cookie);
|
|
59
|
-
} catch {}
|
|
60
|
-
const parts = [];
|
|
61
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
62
|
-
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) continue;
|
|
63
|
-
parts.push(`${key}=${value.value}`);
|
|
64
|
-
}
|
|
65
|
-
return parts.join("; ");
|
|
20
|
+
const STORED_COOKIES_KEY = "better-auth_cookie";
|
|
21
|
+
/**
|
|
22
|
+
* The stored cookies, with the session the website's Worker signed in with added: it exchanges a
|
|
23
|
+
* sign-in's one-time token itself and sets only the mirror. Read storage through this alone,
|
|
24
|
+
* since reading it writes the mirror back from storage.
|
|
25
|
+
*/
|
|
26
|
+
function readStoredCookies(storage, key = STORED_COOKIES_KEY) {
|
|
27
|
+
const stored = storage.getItem(key) || "{}";
|
|
28
|
+
if (typeof document === "undefined") return stored;
|
|
29
|
+
const adopted = withCookieHeader(stored, readServerAuthCookie(document.cookie));
|
|
30
|
+
if (!adopted) return stored;
|
|
31
|
+
storage.setItem(key, adopted);
|
|
32
|
+
return adopted;
|
|
66
33
|
}
|
|
67
34
|
/**
|
|
68
35
|
* Read the cross-domain auth cookie from localStorage and return it as a
|
|
@@ -70,7 +37,7 @@ function getCookie(cookie) {
|
|
|
70
37
|
*/
|
|
71
38
|
function getAuthCookieHeader() {
|
|
72
39
|
if (typeof window === "undefined") return "";
|
|
73
|
-
const cookie = getCookie(localStorage
|
|
40
|
+
const cookie = getCookie(readStoredCookies(localStorage));
|
|
74
41
|
writeServerAuthCookie(cookie);
|
|
75
42
|
return cookie;
|
|
76
43
|
}
|
|
@@ -87,10 +54,7 @@ function crossDomainClient(opts = {}) {
|
|
|
87
54
|
getActions(_, $store) {
|
|
88
55
|
store = $store;
|
|
89
56
|
return {
|
|
90
|
-
getCookie: () =>
|
|
91
|
-
const cookie = storage?.getItem(cookieName);
|
|
92
|
-
return getCookie(cookie || "{}");
|
|
93
|
-
},
|
|
57
|
+
getCookie: () => storage ? getCookie(readStoredCookies(storage, cookieName)) : "",
|
|
94
58
|
updateSession: () => {
|
|
95
59
|
$store.notify("$sessionSignal");
|
|
96
60
|
},
|
|
@@ -143,7 +107,7 @@ function crossDomainClient(opts = {}) {
|
|
|
143
107
|
options
|
|
144
108
|
};
|
|
145
109
|
options = options || {};
|
|
146
|
-
const cookie = getCookie(storage
|
|
110
|
+
const cookie = getCookie(readStoredCookies(storage, cookieName));
|
|
147
111
|
writeServerAuthCookie(cookie);
|
|
148
112
|
options.credentials = getAuthRequestCredentials(cookie);
|
|
149
113
|
options.headers = {
|
|
@@ -181,6 +145,8 @@ function createCamoxAuthClient(apiUrl) {
|
|
|
181
145
|
/**
|
|
182
146
|
* Process a `?ott=` one-time token from the URL before the provider mounts.
|
|
183
147
|
* Verifies the token against the API backend and notifies the session store.
|
|
148
|
+
* The Worker exchanges a studio sign-in's token before rendering, so this handles a preview
|
|
149
|
+
* link's, and any token the Worker couldn't exchange.
|
|
184
150
|
*
|
|
185
151
|
* Reports completion and explicit handoff failures instead of silently showing live content.
|
|
186
152
|
* Keeps the handoff marker until SSR confirms authentication on the subsequent load.
|
|
@@ -258,7 +224,7 @@ function useProjectUuid() {
|
|
|
258
224
|
}
|
|
259
225
|
const subscribeToHydration = () => () => {};
|
|
260
226
|
function hasStoredAuthCookie() {
|
|
261
|
-
return getCookie(localStorage
|
|
227
|
+
return getCookie(readStoredCookies(localStorage)) !== "";
|
|
262
228
|
}
|
|
263
229
|
const noSubscription = () => () => {};
|
|
264
230
|
/**
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
//#region src/lib/server-auth-cookie.ts
|
|
2
2
|
const SERVER_AUTH_COOKIE_NAME = "camox_auth_cookie";
|
|
3
|
+
/** How long the mirror lasts. The API still refuses a session that expired before it. */
|
|
4
|
+
const SERVER_AUTH_COOKIE_MAX_AGE = 2592e3;
|
|
3
5
|
function buildClearServerAuthCookieHeader() {
|
|
4
6
|
return `${SERVER_AUTH_COOKIE_NAME}=; Path=/; SameSite=Lax; Max-Age=0`;
|
|
5
7
|
}
|
|
8
|
+
/** Sets the mirror to a session, as a `Cookie` header's value. */
|
|
9
|
+
function buildServerAuthCookieHeader(cookie, { secure }) {
|
|
10
|
+
return `${SERVER_AUTH_COOKIE_NAME}=${encodeURIComponent(cookie)}; Path=/; SameSite=Lax; Max-Age=${SERVER_AUTH_COOKIE_MAX_AGE}${secure ? "; Secure" : ""}`;
|
|
11
|
+
}
|
|
6
12
|
/**
|
|
7
13
|
* The session to forward to the API for validation; cookie presence is not authentication. Only
|
|
8
14
|
* the studio's session counts, which the SDK mirrors into `camox_auth_cookie`. Better Auth's own
|
|
@@ -10,7 +16,11 @@ function buildClearServerAuthCookieHeader() {
|
|
|
10
16
|
* host (ADR 0028). Mirrored in apps/dispatch/src/previews.ts: keep the two in sync.
|
|
11
17
|
*/
|
|
12
18
|
function getServerAuthCookieHeader(headers) {
|
|
13
|
-
|
|
19
|
+
return readServerAuthCookie(headers.get("Cookie") ?? "");
|
|
20
|
+
}
|
|
21
|
+
/** The mirror's session in a `Cookie` header's value, or `document.cookie`. */
|
|
22
|
+
function readServerAuthCookie(cookieHeader) {
|
|
23
|
+
const mirror = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${SERVER_AUTH_COOKIE_NAME}=`));
|
|
14
24
|
if (!mirror) return "";
|
|
15
25
|
try {
|
|
16
26
|
return decodeURIComponent(mirror.slice(18));
|
|
@@ -20,4 +30,4 @@ function getServerAuthCookieHeader(headers) {
|
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
//#endregion
|
|
23
|
-
export { SERVER_AUTH_COOKIE_NAME, buildClearServerAuthCookieHeader, getServerAuthCookieHeader };
|
|
33
|
+
export { SERVER_AUTH_COOKIE_NAME, buildClearServerAuthCookieHeader, buildServerAuthCookieHeader, getServerAuthCookieHeader, readServerAuthCookie };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//#region src/lib/stored-auth-cookies.ts
|
|
2
|
+
function parseSetCookieHeader(header) {
|
|
3
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
4
|
+
header.split(", ").forEach((cookie) => {
|
|
5
|
+
const [nameValue, ...attributes] = cookie.split("; ");
|
|
6
|
+
const [name, value] = nameValue.split("=");
|
|
7
|
+
const cookieObj = { value };
|
|
8
|
+
attributes.forEach((attr) => {
|
|
9
|
+
const [attrName, attrValue] = attr.split("=");
|
|
10
|
+
cookieObj[attrName.toLowerCase()] = attrValue;
|
|
11
|
+
});
|
|
12
|
+
cookieMap.set(name, cookieObj);
|
|
13
|
+
});
|
|
14
|
+
return cookieMap;
|
|
15
|
+
}
|
|
16
|
+
function getSetCookie(header, prevCookie) {
|
|
17
|
+
const parsed = parseSetCookieHeader(header);
|
|
18
|
+
let toSetCookie = {};
|
|
19
|
+
parsed.forEach((cookie, key) => {
|
|
20
|
+
const expiresAt = cookie["expires"];
|
|
21
|
+
const maxAge = cookie["max-age"];
|
|
22
|
+
let expires = null;
|
|
23
|
+
if (expiresAt) expires = new Date(String(expiresAt));
|
|
24
|
+
else if (maxAge) expires = new Date(Date.now() + Number(maxAge) * 1e3);
|
|
25
|
+
toSetCookie[key] = {
|
|
26
|
+
value: cookie["value"],
|
|
27
|
+
expires: expires ? expires.toISOString() : null
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
if (prevCookie) try {
|
|
31
|
+
toSetCookie = {
|
|
32
|
+
...JSON.parse(prevCookie),
|
|
33
|
+
...toSetCookie
|
|
34
|
+
};
|
|
35
|
+
} catch {}
|
|
36
|
+
return JSON.stringify(toSetCookie);
|
|
37
|
+
}
|
|
38
|
+
function getCookie(cookie) {
|
|
39
|
+
let parsed = {};
|
|
40
|
+
try {
|
|
41
|
+
parsed = JSON.parse(cookie);
|
|
42
|
+
} catch {}
|
|
43
|
+
const parts = [];
|
|
44
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
45
|
+
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) continue;
|
|
46
|
+
parts.push(`${key}=${value.value}`);
|
|
47
|
+
}
|
|
48
|
+
return parts.join("; ");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The stored cookies with those of a `Cookie` header's value added, when it holds one they don't:
|
|
52
|
+
* a session the website's Worker signed in with. Null when they hold it already, even expired.
|
|
53
|
+
*/
|
|
54
|
+
function withCookieHeader(stored, header) {
|
|
55
|
+
let parsed = {};
|
|
56
|
+
try {
|
|
57
|
+
parsed = JSON.parse(stored);
|
|
58
|
+
} catch {}
|
|
59
|
+
let added = false;
|
|
60
|
+
for (const pair of header.split("; ")) {
|
|
61
|
+
const separator = pair.indexOf("=");
|
|
62
|
+
if (separator <= 0) continue;
|
|
63
|
+
const name = pair.slice(0, separator);
|
|
64
|
+
const value = pair.slice(separator + 1);
|
|
65
|
+
if (parsed[name]?.value === value) continue;
|
|
66
|
+
parsed[name] = {
|
|
67
|
+
value,
|
|
68
|
+
expires: null
|
|
69
|
+
};
|
|
70
|
+
added = true;
|
|
71
|
+
}
|
|
72
|
+
return added ? JSON.stringify(parsed) : null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { getCookie, getSetCookie, parseSetCookieHeader, withCookieHeader };
|
package/dist/lib/use-thread.js
CHANGED
|
@@ -152,10 +152,10 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
152
152
|
let t9;
|
|
153
153
|
if ($[23] !== socket || $[24] !== unaccepted) {
|
|
154
154
|
t9 = () => {
|
|
155
|
-
for (const [operationId_2,
|
|
155
|
+
for (const [operationId_2, message] of unaccepted) transmit(socket, {
|
|
156
156
|
type: "send",
|
|
157
157
|
operationId: operationId_2,
|
|
158
|
-
|
|
158
|
+
...message
|
|
159
159
|
});
|
|
160
160
|
};
|
|
161
161
|
$[23] = socket;
|
|
@@ -200,15 +200,19 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
200
200
|
React.useEffect(t12, t13);
|
|
201
201
|
let t14;
|
|
202
202
|
if ($[34] !== sent || $[35] !== socket) {
|
|
203
|
-
t14 = (
|
|
203
|
+
t14 = (text, where) => {
|
|
204
204
|
const operationId_3 = crypto.randomUUID();
|
|
205
|
+
const message_0 = where ? {
|
|
206
|
+
text,
|
|
207
|
+
where
|
|
208
|
+
} : { text };
|
|
205
209
|
sent.add(operationId_3);
|
|
206
210
|
setError(void 0);
|
|
207
|
-
setUnaccepted((current_3) => new Map(current_3).set(operationId_3,
|
|
211
|
+
setUnaccepted((current_3) => new Map(current_3).set(operationId_3, message_0));
|
|
208
212
|
transmit(socket, {
|
|
209
213
|
type: "send",
|
|
210
214
|
operationId: operationId_3,
|
|
211
|
-
|
|
215
|
+
...message_0
|
|
212
216
|
});
|
|
213
217
|
};
|
|
214
218
|
$[34] = sent;
|
package/dist/package.js
CHANGED