camox 0.58.1 → 0.60.2
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/createBlock.js +1 -1
- package/dist/core/editing/createEditableBlock.js +2 -2
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CamoxCanvas.js +2 -2
- package/dist/features/canvas/CanvasOverlays.js +1 -1
- package/dist/features/canvas/sidebar/LayoutPageSeo.js +1 -1
- package/dist/features/canvas/sidebar/PageInspector.js +1 -1
- package/dist/features/content/CamoxContent.js +1 -1
- package/dist/features/content/components/MissingFromLocale.js +1 -1
- package/dist/features/page/CuratedPageContent.js +1 -1
- package/dist/features/preview/CamoxPreview.js +3 -3
- package/dist/features/preview/components/AddBlockSheet.js +1 -1
- package/dist/features/preview/components/AssetLightbox.js +1 -1
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/CreatePageModal.js +2 -2
- package/dist/features/preview/components/FieldOverlayStyles.js +1 -1
- package/dist/features/preview/components/MobilePreviewDrawer.js +1 -1
- package/dist/features/preview/components/Overlays.js +1 -1
- package/dist/features/preview/components/PageInfo.js +1 -1
- package/dist/features/preview/components/PagePicker.js +1 -1
- 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 +1 -1
- package/dist/features/preview/components/SelectionEditor.js +2 -2
- package/dist/features/preview/components/StudioEditingFallback.js +1 -1
- package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
- package/dist/features/provider/CamoxProvider.js +1 -1
- package/dist/features/provider/CoreCamoxProvider.js +3 -3
- package/dist/features/provider/components/CommandPalette.js +1 -1
- package/dist/features/renderer/RendererApp.js +187 -103
- package/dist/features/renderer/rendererHost.js +3 -7
- package/dist/features/routes/pageRuntime.d.ts +2 -5
- package/dist/features/routes/pageRuntime.js +1 -2
- package/dist/features/runtime/RuntimeChrome.js +1 -1
- package/dist/features/runtime/loopbackFetch.d.ts +8 -0
- package/dist/features/runtime/navigationTarget.js +1 -2
- package/dist/features/runtime/pageApp.js +1 -1
- package/dist/features/runtime/publicCache.d.ts +21 -0
- package/dist/features/runtime/publishingDraft.d.ts +4 -0
- package/dist/features/runtime/rendererClient.js +1 -1
- package/dist/features/runtime/runtime.d.ts +0 -5
- package/dist/features/runtime/runtime.js +80 -33
- package/dist/features/runtime/worker.js +4 -7
- 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/FaviconSettings.js +1 -1
- package/dist/features/settings/SocialProfilesSettings.js +284 -151
- package/dist/features/studio/CamoxStudio.js +1 -1
- package/dist/features/studio/FollowAgentProvider.js +72 -13
- package/dist/features/studio/components/ChatWidget.js +86 -44
- package/dist/features/studio/components/DraftsControl.js +232 -201
- package/dist/features/studio/components/LocalePicker.js +2 -2
- package/dist/features/studio/components/Navbar.js +3 -3
- package/dist/features/studio/components/Patrol.js +312 -209
- package/dist/features/studio/components/ProjectMenu.js +2 -2
- package/dist/features/studio/components/ReviewDraftSheet.js +9 -15
- 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 +216 -64
- package/dist/features/studio/components/UserButton.js +2 -2
- package/dist/features/studio/draftLabel.js +1 -2
- package/dist/features/studio/draftNotice.js +0 -1
- package/dist/features/studio/editorWhereContext.js +11 -0
- package/dist/features/studio/showInCanvas.js +1 -1
- package/dist/features/studio/useEditorSelection.js +135 -0
- package/dist/features/vite/definitionsSync.js +14 -60
- package/dist/features/vite/devSignIn.js +1 -1
- package/dist/features/vite/hostedChecks.js +1 -1
- package/dist/features/vite/runtimeDev.js +2 -2
- package/dist/features/vite/sdkBundleBuild.js +74 -0
- package/dist/features/vite/staticAssetHeaders.js +7 -4
- package/dist/features/vite/vite.d.ts +8 -7
- package/dist/features/vite/vite.js +67 -28
- package/dist/lib/api-client-server.js +25 -8
- package/dist/lib/api-client.js +2 -6
- package/dist/lib/auth.js +25 -59
- package/dist/lib/draft-scope.js +5 -25
- package/dist/lib/preview-handoff.js +1 -1
- package/dist/lib/server-auth-cookie.js +23 -11
- package/dist/lib/stored-auth-cookies.js +76 -0
- package/dist/lib/studio-reads.js +1 -1
- package/dist/lib/use-thread.js +40 -40
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +17 -4
- package/skills/camox/references/block-definitions.md +1 -1
- package/dist/features/vite/publishSeededContent.js +0 -30
- package/skills/camox-cli/SKILL.md +0 -15
- package/skills/camox-cli/references/cli-common.md +0 -58
- package/skills/camox-cli/references/cli-content.md +0 -181
- package/skills/camox-cli/references/cli-publishing.md +0 -26
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { serializeJsonForHtml } from "../../lib/html.js";
|
|
2
2
|
import { createRequestContext } from "../../core/requestContext.js";
|
|
3
|
-
import { buildClearServerAuthCookieHeader, getServerAuthCookieHeader } from "../../lib/server-auth-cookie.js";
|
|
4
3
|
import { UNNAMED_DEFAULT_LOCALE, localizedPath, parseLocalePath } from "../../lib/locale-path.js";
|
|
5
4
|
import { draftNamedBy } from "../../lib/draft-scope.js";
|
|
5
|
+
import { buildClearServerAuthCookieHeader, buildServerAuthCookieHeader, getServerAuthCookieHeader } from "../../lib/server-auth-cookie.js";
|
|
6
|
+
import { getCookie, getSetCookie } from "../../lib/stored-auth-cookies.js";
|
|
6
7
|
import { ARTIFACTS_PATH_PREFIX, RUNTIME_ROUTE_PATHS, matchRuntimeOwnedRoute } from "./runtimeRoutes.js";
|
|
7
8
|
import { reads } from "../../lib/studio-reads.js";
|
|
8
9
|
import { asCollectionItem, recordMarkdownTemplate, recordPageValues } from "../../core/recordItem.js";
|
|
@@ -26,7 +27,7 @@ import { getPageBlockTypes } from "./pageBlockTypes.js";
|
|
|
26
27
|
import { withPageUrls } from "./structuredData.js";
|
|
27
28
|
import { curatedPageDescription, pageRecords, placedBlockNodes, withStructuredData } from "./pageGraph.js";
|
|
28
29
|
import { createProjectLogoResponse, projectLogo } from "./projectLogo.js";
|
|
29
|
-
import {
|
|
30
|
+
import { LOCALE_HEADER } from "@camox/api-contract/drafts";
|
|
30
31
|
import { QueryClient, dehydrate } from "@tanstack/react-query";
|
|
31
32
|
import { createHead, renderSSRHead } from "@unhead/react/server";
|
|
32
33
|
|
|
@@ -52,20 +53,16 @@ function getRuntimePathname(url, runtimeBasePath = DEFAULT_RUNTIME_BASE_PATH) {
|
|
|
52
53
|
if (!pathname.startsWith(`${basePath}/`)) return null;
|
|
53
54
|
return pathname.slice(basePath.length) || "/";
|
|
54
55
|
}
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
* Markdown ignore it: they read Live.
|
|
58
|
-
*/
|
|
59
|
-
function getRequestDraftId(request, options) {
|
|
60
|
-
if (options.developmentDraft) return DEVELOPMENT_DRAFT;
|
|
56
|
+
/** The draft the request's URL names, if any. Sitemaps and Markdown ignore it: they read Live. */
|
|
57
|
+
function getRequestDraftId(request) {
|
|
61
58
|
return draftNamedBy(request.url) ?? void 0;
|
|
62
59
|
}
|
|
63
60
|
/**
|
|
64
61
|
* Whether a response may show what only this visitor sees: a session, or a draft named in the
|
|
65
62
|
* URL. Shared caches must never keep it.
|
|
66
63
|
*/
|
|
67
|
-
function isPrivateRender(request
|
|
68
|
-
return !!getServerAuthCookieHeader(request.headers) || getRequestDraftId(request
|
|
64
|
+
function isPrivateRender(request) {
|
|
65
|
+
return !!getServerAuthCookieHeader(request.headers) || getRequestDraftId(request) !== void 0;
|
|
69
66
|
}
|
|
70
67
|
/** The routes whose response is the same for every visitor, unless the request is private. */
|
|
71
68
|
const PUBLIC_ROUTE_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -83,7 +80,7 @@ const PUBLIC_ROUTE_KINDS = /* @__PURE__ */ new Set([
|
|
|
83
80
|
*/
|
|
84
81
|
function isPublicRequest(request, options = {}) {
|
|
85
82
|
if (request.method !== "GET" && request.method !== "HEAD") return false;
|
|
86
|
-
if (isPrivateRender(request
|
|
83
|
+
if (isPrivateRender(request) || new URL(request.url).searchParams.has("ott")) return false;
|
|
87
84
|
const pathname = getRuntimePathname(request.url, options.runtimeBasePath);
|
|
88
85
|
return pathname !== null && PUBLIC_ROUTE_KINDS.has(matchRuntimeRoute(pathname).kind);
|
|
89
86
|
}
|
|
@@ -316,7 +313,7 @@ async function createOgResponse(request, options) {
|
|
|
316
313
|
source.context,
|
|
317
314
|
style
|
|
318
315
|
])),
|
|
319
|
-
"Cache-Control": isPrivateRender(request
|
|
316
|
+
"Cache-Control": isPrivateRender(request) ? "private, no-store" : "public, no-cache"
|
|
320
317
|
};
|
|
321
318
|
if (namesEtag(request, headers.ETag)) return new Response(null, {
|
|
322
319
|
status: 304,
|
|
@@ -337,7 +334,7 @@ async function readPageImageSource(request, options, app) {
|
|
|
337
334
|
const { project } = await resolveRequestMember(request, options);
|
|
338
335
|
const member = project !== void 0;
|
|
339
336
|
const authCookieHeader = member ? getServerAuthCookieHeader(request.headers) : void 0;
|
|
340
|
-
const requestedDraft = getRequestDraftId(request
|
|
337
|
+
const requestedDraft = getRequestDraftId(request);
|
|
341
338
|
const api = (draftId) => createServerApiClient(apiUrl, {
|
|
342
339
|
authCookieHeader,
|
|
343
340
|
draftId,
|
|
@@ -534,11 +531,11 @@ function hydrationInputFor(input, html) {
|
|
|
534
531
|
/**
|
|
535
532
|
* The render input with its artifacts loaded by URL, where a visitor reads Live: each artifact
|
|
536
533
|
* source becomes a reference to the document the website serves, so neither the page's HTML nor
|
|
537
|
-
* its data carries a source, and the client renders the frames the server did. The studio
|
|
538
|
-
*
|
|
534
|
+
* its data carries a source, and the client renders the frames the server did. The studio and
|
|
535
|
+
* drafts keep inlined sources, so an agent's change shows at once.
|
|
539
536
|
*/
|
|
540
537
|
async function withArtifactsByUrl(input, options) {
|
|
541
|
-
if (input.presentation !== "public" || input.draftId
|
|
538
|
+
if (input.presentation !== "public" || input.draftId) return input;
|
|
542
539
|
const shell = await readArtifactShell(options);
|
|
543
540
|
const artifactsPath = `${input.runtimeBasePath}${ARTIFACTS_PATH_PREFIX}${shell.hash}/`;
|
|
544
541
|
return {
|
|
@@ -551,10 +548,10 @@ function renderStudioThemeScript(enabled) {
|
|
|
551
548
|
}
|
|
552
549
|
/**
|
|
553
550
|
* The analytics providers a render counts its reader with: only a visitor, meaning someone the
|
|
554
|
-
* API didn't confirm as a member, on a Live page.
|
|
551
|
+
* API didn't confirm as a member, on a Live page.
|
|
555
552
|
*/
|
|
556
|
-
function visitorAnalytics(
|
|
557
|
-
if (render.studio || render.draftId
|
|
553
|
+
function visitorAnalytics(render, project) {
|
|
554
|
+
if (render.studio || render.draftId) return void 0;
|
|
558
555
|
return configuredProviders(project.analytics);
|
|
559
556
|
}
|
|
560
557
|
/** Whether a request is a preview link's token handoff, which signs in before reading anything. */
|
|
@@ -563,6 +560,51 @@ function isPreviewHandoff(request, options) {
|
|
|
563
560
|
return searchParams.has("camox-preview") && searchParams.has("ott") && !!options.apiUrl && !!options.authenticationUrl && !!options.projectUuid && !!options.renderPage;
|
|
564
561
|
}
|
|
565
562
|
/**
|
|
563
|
+
* Whether a request lands from the studio's sign-in with its one-time token, which the Worker
|
|
564
|
+
* exchanges itself. A preview link's handoff checks its target in the browser first.
|
|
565
|
+
*/
|
|
566
|
+
function isSignInHandoff(request) {
|
|
567
|
+
const { searchParams } = new URL(request.url);
|
|
568
|
+
return request.method === "GET" && searchParams.has("ott") && !searchParams.has("camox-preview");
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Exchanges a sign-in's one-time token for the studio's session, sets the cookie that mirrors it,
|
|
572
|
+
* and sends the browser back to the URL without the token. The page then renders for the member
|
|
573
|
+
* at once, rather than for a visitor, then again once the browser signed in. Null when the
|
|
574
|
+
* exchange fails: the page loads with the token, and the browser tries it and says what failed.
|
|
575
|
+
*/
|
|
576
|
+
async function createSignInResponse(request, apiUrl) {
|
|
577
|
+
const url = new URL(request.url);
|
|
578
|
+
let setCookie;
|
|
579
|
+
try {
|
|
580
|
+
const response = await fetch(`${apiUrl.replace(/\/+$/, "")}/api/auth/one-time-token/verify`, {
|
|
581
|
+
method: "POST",
|
|
582
|
+
headers: {
|
|
583
|
+
"Content-Type": "application/json",
|
|
584
|
+
"Better-Auth-Cookie": ""
|
|
585
|
+
},
|
|
586
|
+
body: JSON.stringify({ token: url.searchParams.get("ott") })
|
|
587
|
+
});
|
|
588
|
+
if (!response.ok) return null;
|
|
589
|
+
setCookie = response.headers.get("Set-Better-Auth-Cookie");
|
|
590
|
+
} catch (error) {
|
|
591
|
+
console.error("[camox] Sign-in token exchange failed.", error);
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
const session = setCookie ? getCookie(getSetCookie(setCookie)) : "";
|
|
595
|
+
if (!session) return null;
|
|
596
|
+
url.searchParams.delete("ott");
|
|
597
|
+
return new Response(null, {
|
|
598
|
+
status: 302,
|
|
599
|
+
headers: {
|
|
600
|
+
Location: `${url.pathname}${url.search}`,
|
|
601
|
+
"Cache-Control": "private, no-store",
|
|
602
|
+
"Referrer-Policy": "no-referrer",
|
|
603
|
+
"Set-Cookie": buildServerAuthCookieHeader(session, { secure: url.protocol === "https:" })
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
566
608
|
* The alternates of the page a request renders, where it exists in each of the scope's locales,
|
|
567
609
|
* and its head with their `hreflang` links. Without a head, there is none to add them to.
|
|
568
610
|
*/
|
|
@@ -757,7 +799,7 @@ function readCuratedPage(options, request, { locale, path }) {
|
|
|
757
799
|
result: loadCamoxPageForRequest({
|
|
758
800
|
apiUrl: options.apiUrl,
|
|
759
801
|
authCookieHeader: getServerAuthCookieHeader(request.headers),
|
|
760
|
-
draftId: getRequestDraftId(request
|
|
802
|
+
draftId: getRequestDraftId(request),
|
|
761
803
|
locale,
|
|
762
804
|
origin: new URL(request.url).origin,
|
|
763
805
|
pathname: path,
|
|
@@ -806,7 +848,7 @@ function curatedPageLocaleReads(options, request, located, queryClient) {
|
|
|
806
848
|
draftId,
|
|
807
849
|
queryClient
|
|
808
850
|
});
|
|
809
|
-
if (!(!getRequestDraftId(request
|
|
851
|
+
if (!(!getRequestDraftId(request) || !authCookieHeader)) return forDraft;
|
|
810
852
|
const live = forDraft(void 0);
|
|
811
853
|
if (located.locales.length > 1) for (const locale of located.locales) {
|
|
812
854
|
if (locale.tag === located.locale.tag || locale.isDefault) continue;
|
|
@@ -837,7 +879,7 @@ async function createPageHtmlResponse({ options, pathname, located, request, pag
|
|
|
837
879
|
Vary: "Cookie",
|
|
838
880
|
Link: llmsTxtLinkHeader(options)
|
|
839
881
|
});
|
|
840
|
-
if (isPrivateRender(request
|
|
882
|
+
if (isPrivateRender(request)) headers.set("Cache-Control", "private, no-store");
|
|
841
883
|
if (result.shouldClearAuthCookie) headers.append("Set-Cookie", buildClearServerAuthCookieHeader());
|
|
842
884
|
const camoxApp = await options.getCamoxApp?.();
|
|
843
885
|
const document = await options.getDocument?.() ?? {};
|
|
@@ -854,7 +896,7 @@ async function createPageHtmlResponse({ options, pathname, located, request, pag
|
|
|
854
896
|
const dehydratedState = dehydrate(queryClient);
|
|
855
897
|
const { project } = result;
|
|
856
898
|
const studio = project !== void 0;
|
|
857
|
-
const analytics = visitorAnalytics(
|
|
899
|
+
const analytics = visitorAnalytics({
|
|
858
900
|
studio,
|
|
859
901
|
draftId: result.draftId
|
|
860
902
|
}, result.data.page.project);
|
|
@@ -1071,7 +1113,7 @@ async function createLayoutMarkdownDataResponse(options, request, pathname) {
|
|
|
1071
1113
|
if (!match || matchLocalizedRoute(located.path)?.kind !== "page") return new Response("Not found", { status: 404 });
|
|
1072
1114
|
const { project, clearAuthCookie } = await resolveRequestMember(request, options);
|
|
1073
1115
|
const headers = {
|
|
1074
|
-
...isPrivateRender(request
|
|
1116
|
+
...isPrivateRender(request) ? { "Cache-Control": "private, no-store" } : {},
|
|
1075
1117
|
Vary: "Cookie",
|
|
1076
1118
|
...clearAuthCookie ? { "Set-Cookie": buildClearServerAuthCookieHeader() } : {}
|
|
1077
1119
|
};
|
|
@@ -1082,7 +1124,7 @@ async function createLayoutMarkdownDataResponse(options, request, pathname) {
|
|
|
1082
1124
|
}, {
|
|
1083
1125
|
member: project !== void 0,
|
|
1084
1126
|
authCookieHeader: getServerAuthCookieHeader(request.headers),
|
|
1085
|
-
requestedDraft: getRequestDraftId(request
|
|
1127
|
+
requestedDraft: getRequestDraftId(request)
|
|
1086
1128
|
});
|
|
1087
1129
|
return Response.json({ markdown }, { headers });
|
|
1088
1130
|
} catch (error) {
|
|
@@ -1103,7 +1145,7 @@ async function createDerivedResponse(options, pathname, located, request, { data
|
|
|
1103
1145
|
const { project, clearAuthCookie } = await resolveRequestMember(request, options);
|
|
1104
1146
|
const studio = project !== void 0;
|
|
1105
1147
|
const authCookieHeader = studio ? getServerAuthCookieHeader(request.headers) : void 0;
|
|
1106
|
-
const requestedDraft = getRequestDraftId(request
|
|
1148
|
+
const requestedDraft = getRequestDraftId(request);
|
|
1107
1149
|
const readLayout = () => readDraftOrLive(requestedDraft, studio, (draftId) => createServerApiClient(options.apiUrl, {
|
|
1108
1150
|
authCookieHeader,
|
|
1109
1151
|
draftId,
|
|
@@ -1183,7 +1225,7 @@ async function createDerivedResponse(options, pathname, located, request, { data
|
|
|
1183
1225
|
draftId: read.draftId
|
|
1184
1226
|
})
|
|
1185
1227
|
});
|
|
1186
|
-
const analytics = dataOnly ? void 0 : visitorAnalytics(
|
|
1228
|
+
const analytics = dataOnly ? void 0 : visitorAnalytics({
|
|
1187
1229
|
studio,
|
|
1188
1230
|
draftId: read.draftId
|
|
1189
1231
|
}, shared.project);
|
|
@@ -1220,7 +1262,7 @@ async function createDerivedResponse(options, pathname, located, request, { data
|
|
|
1220
1262
|
const document = await options.getDocument?.() ?? {};
|
|
1221
1263
|
preparePreviewDocument(input, options, document);
|
|
1222
1264
|
if (dataOnly) return Response.json(input, { headers: {
|
|
1223
|
-
...isPrivateRender(request
|
|
1265
|
+
...isPrivateRender(request) ? { "Cache-Control": "private, no-store" } : {},
|
|
1224
1266
|
Vary: "Cookie",
|
|
1225
1267
|
...clearAuthCookie ? { "Set-Cookie": buildClearServerAuthCookieHeader() } : {}
|
|
1226
1268
|
} });
|
|
@@ -1230,7 +1272,7 @@ async function createDerivedResponse(options, pathname, located, request, { data
|
|
|
1230
1272
|
"Content-Type": "text/html; charset=utf-8",
|
|
1231
1273
|
Vary: "Cookie",
|
|
1232
1274
|
Link: llmsTxtLinkHeader(options),
|
|
1233
|
-
...isPrivateRender(request
|
|
1275
|
+
...isPrivateRender(request) ? { "Cache-Control": "private, no-store" } : {},
|
|
1234
1276
|
...clearAuthCookie ? { "Set-Cookie": buildClearServerAuthCookieHeader() } : {}
|
|
1235
1277
|
} });
|
|
1236
1278
|
} catch (error) {
|
|
@@ -1261,7 +1303,8 @@ async function createStudioHtmlResponse({ match, options, pathname, located, req
|
|
|
1261
1303
|
routeKind: match.kind,
|
|
1262
1304
|
runtimeBasePath: normalizeRuntimeBasePath(options.runtimeBasePath),
|
|
1263
1305
|
locale: located.locale,
|
|
1264
|
-
locales: located.locales
|
|
1306
|
+
locales: located.locales,
|
|
1307
|
+
draftId: project ? getRequestDraftId(request) : void 0
|
|
1265
1308
|
};
|
|
1266
1309
|
if (dataOnly) return Response.json(studioRenderInput, { headers: {
|
|
1267
1310
|
"Cache-Control": "private, no-store",
|
|
@@ -1319,7 +1362,7 @@ async function createCanvasOnlyResponse({ options, pathname, located, request, d
|
|
|
1319
1362
|
loaderData: null,
|
|
1320
1363
|
dehydratedState: dehydrate(new QueryClient()),
|
|
1321
1364
|
canvasOnly: true,
|
|
1322
|
-
draftId: studio ? getRequestDraftId(request
|
|
1365
|
+
draftId: studio ? getRequestDraftId(request) : void 0
|
|
1323
1366
|
};
|
|
1324
1367
|
const headers = {
|
|
1325
1368
|
"Cache-Control": "private, no-store",
|
|
@@ -1353,7 +1396,7 @@ async function createPageDataResponse({ options, pathname, located, request, pag
|
|
|
1353
1396
|
"Content-Type": "application/json; charset=utf-8",
|
|
1354
1397
|
Vary: "Cookie"
|
|
1355
1398
|
});
|
|
1356
|
-
if (isPrivateRender(request
|
|
1399
|
+
if (isPrivateRender(request)) headers.set("Cache-Control", "private, no-store");
|
|
1357
1400
|
if (result.shouldClearAuthCookie) headers.append("Set-Cookie", buildClearServerAuthCookieHeader());
|
|
1358
1401
|
const camoxApp = await options.getCamoxApp?.();
|
|
1359
1402
|
const { alternates, head } = await readAlternates(request, options, {
|
|
@@ -1433,6 +1476,10 @@ async function handleCamoxRequest(request, options = {}) {
|
|
|
1433
1476
|
pathname,
|
|
1434
1477
|
request
|
|
1435
1478
|
});
|
|
1479
|
+
if (options.apiUrl && isSignInHandoff(request)) {
|
|
1480
|
+
const signedIn = await createSignInResponse(request, options.apiUrl);
|
|
1481
|
+
if (signedIn) return signedIn;
|
|
1482
|
+
}
|
|
1436
1483
|
const { apiUrl, projectUuid } = options;
|
|
1437
1484
|
const markdownPathname = parseMarkdownPath(pathname);
|
|
1438
1485
|
if (apiUrl && projectUuid && (markdownPathname || prefersMarkdown(request.headers.get("Accept") ?? ""))) {
|
|
@@ -1529,7 +1576,7 @@ async function locateRequest(request, options, pathname) {
|
|
|
1529
1576
|
apiUrl,
|
|
1530
1577
|
projectUuid,
|
|
1531
1578
|
authCookieHeader: getServerAuthCookieHeader(request.headers),
|
|
1532
|
-
draftId: getRequestDraftId(request
|
|
1579
|
+
draftId: getRequestDraftId(request)
|
|
1533
1580
|
}) : [UNNAMED_DEFAULT_LOCALE];
|
|
1534
1581
|
return {
|
|
1535
1582
|
...parseLocalePath(pathname, locales),
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { rememberPublishingDraft } from "
|
|
2
|
-
import { fetchLocalhostOnLoopback } from "./loopbackFetch.js";
|
|
3
|
-
import { PUBLIC_CACHE_NAME, readLiveCacheKey, respondThroughPublicCache } from "./publicCache.js";
|
|
4
|
-
import { shouldHandleRequest, withDevHtml } from "./workerRequest.js";
|
|
1
|
+
import { PUBLIC_CACHE_NAME, fetchLocalhostOnLoopback, readLiveCacheKey, rememberPublishingDraft, respondThroughPublicCache, shouldHandleRequest, withDevHtml } from "camox/_internal/workerRuntime";
|
|
5
2
|
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
6
3
|
import { devHtml, handleCamoxRequest, isPublicRequest, publicCacheSource, readDefinitionSet, runtimeBasePath } from "virtual:camox/server";
|
|
7
4
|
|
|
@@ -16,9 +13,9 @@ function notFound() {
|
|
|
16
13
|
return new Response("Not found", { status: 404 });
|
|
17
14
|
}
|
|
18
15
|
/**
|
|
19
|
-
* Answers a request, from the edge cache when every visitor sees the same. Dev
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* Answers a request, from the edge cache when every visitor sees the same. Dev serves code that
|
|
17
|
+
* changes on every save, and a Worker calling this one without its context can't keep anything
|
|
18
|
+
* past the response.
|
|
22
19
|
*/
|
|
23
20
|
function respond(request, context) {
|
|
24
21
|
const caches = globalThis.caches;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/features/runtime/workerRequest.d.ts
|
|
2
|
+
export declare function shouldHandleRequest(request: Request, basePath: string): boolean;
|
|
3
|
+
/** Adds what Vite injects into HTML in dev, such as its client and React Refresh. */
|
|
4
|
+
export declare function withDevHtml(response: Response, html: {
|
|
5
|
+
head: string;
|
|
6
|
+
body: string;
|
|
7
|
+
} | null): Promise<Response>;
|
|
8
|
+
//#endregion
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { fetchLocalhostOnLoopback } from "./loopbackFetch.js";
|
|
2
|
+
import { PUBLIC_CACHE_NAME, readLiveCacheKey, respondThroughPublicCache } from "./publicCache.js";
|
|
3
|
+
import { rememberPublishingDraft } from "./publishingDraft.js";
|
|
4
|
+
import { shouldHandleRequest, withDevHtml } from "./workerRequest.js";
|
|
5
|
+
export { PUBLIC_CACHE_NAME, fetchLocalhostOnLoopback, readLiveCacheKey, rememberPublishingDraft, respondThroughPublicCache, shouldHandleRequest, withDevHtml };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { rememberPublishingDraft } from "./publishingDraft.js";
|
|
2
|
+
import { fetchLocalhostOnLoopback } from "./loopbackFetch.js";
|
|
3
|
+
import { PUBLIC_CACHE_NAME, readLiveCacheKey, respondThroughPublicCache } from "./publicCache.js";
|
|
4
|
+
import { shouldHandleRequest, withDevHtml } from "./workerRequest.js";
|
|
5
|
+
|
|
6
|
+
export { PUBLIC_CACHE_NAME, fetchLocalhostOnLoopback, readLiveCacheKey, rememberPublishingDraft, respondThroughPublicCache, shouldHandleRequest, withDevHtml };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SdkBundleTarget } from "./specifiers.js";
|
|
2
|
+
import { SdkBundleSettings } from "./sdkBundleName.js";
|
|
3
|
+
//#region src/features/sdkBundle/buildSdkBundle.d.ts
|
|
4
|
+
/** The manifest each target's folder holds, beside its files. */
|
|
5
|
+
export declare const SDK_BUNDLE_MANIFEST = "sdk-bundle.json";
|
|
6
|
+
export interface SdkBundleManifest {
|
|
7
|
+
name: string;
|
|
8
|
+
target: SdkBundleTarget;
|
|
9
|
+
builderVersion: string;
|
|
10
|
+
/** Each specifier's entry file, from the folder. */
|
|
11
|
+
entries: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/** One target's version of a built SDK Bundle. */
|
|
14
|
+
export interface BuiltSdkBundle {
|
|
15
|
+
name: string;
|
|
16
|
+
/** Its files, every one at the root: entries, chunks and assets. */
|
|
17
|
+
dir: string;
|
|
18
|
+
}
|
|
19
|
+
export type SdkBundleBuild = Record<SdkBundleTarget, BuiltSdkBundle>;
|
|
20
|
+
/** The lockfile a website installed from, and the website's importer in it. */
|
|
21
|
+
export declare function readSdkBundleLockfile(root: string): Promise<{
|
|
22
|
+
lockfile: string;
|
|
23
|
+
importer: string;
|
|
24
|
+
}>;
|
|
25
|
+
/** The names of the website's SDK Bundle, per target, from its lockfile and settings. */
|
|
26
|
+
export declare function sdkBundleNamesFor({ root, settings }: {
|
|
27
|
+
root: string;
|
|
28
|
+
settings: SdkBundleSettings;
|
|
29
|
+
}): Promise<Record<SdkBundleTarget, string>>;
|
|
30
|
+
/**
|
|
31
|
+
* Builds the SDK Bundle of the website in `root`, with its installed packages, into
|
|
32
|
+
* `<outDir>/browser` and `<outDir>/workerd`. Each folder is served or loaded as is, under its own
|
|
33
|
+
* name's path.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildSdkBundle({ root, outDir, settings }: {
|
|
36
|
+
root: string;
|
|
37
|
+
outDir: string;
|
|
38
|
+
settings: SdkBundleSettings;
|
|
39
|
+
}): Promise<SdkBundleBuild>;
|
|
40
|
+
//#endregion
|