@avocadostudio-ai/orchestrator-core 0.26.0 → 0.27.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.
|
@@ -65,7 +65,7 @@ import { resolveCapabilities } from "../cms/adapter.js";
|
|
|
65
65
|
import { mediaSourceFromUnknown } from "../cms/media-sources.js";
|
|
66
66
|
import { extractAccessToken, isAccessGateEnabled, isValidAccessToken, mintAccessToken, verifyAccessPassword } from "../http/access-tokens.js";
|
|
67
67
|
import { editorCredentials } from "../http/editor-credentials.js";
|
|
68
|
-
import { declareLibraryMount, observeLibraryMount } from "./library-mount.js";
|
|
68
|
+
import { clearLibraryDispatch, declareLibraryMount, observeLibraryMount, registerLibraryDispatch } from "./library-mount.js";
|
|
69
69
|
import { checkAuth, resolveAuth, CLOSED_HINT } from "./auth.js";
|
|
70
70
|
import { setSiteAssetLister, invalidateSiteAssets } from "../state/site-assets.js";
|
|
71
71
|
async function buildRuntime(config) {
|
|
@@ -538,9 +538,23 @@ export function createOrchestrator(config = {}) {
|
|
|
538
538
|
// See `library-mount.ts` for why this is not simply a config value.
|
|
539
539
|
if (config.previewUrl)
|
|
540
540
|
declareLibraryMount(`${config.previewUrl.replace(/\/+$/, "")}${basePath}`);
|
|
541
|
+
/*
|
|
542
|
+
* Requests this process's own preview dispatches in-process (see
|
|
543
|
+
* `library-mount.ts`). Membership is the credential: a request that arrived
|
|
544
|
+
* over the network is a different object, so it can never be in the set, and
|
|
545
|
+
* nothing about it — no header, no URL — can put it there. The bypass covers
|
|
546
|
+
* the three GET draft reads the SDK makes and nothing else, so code that
|
|
547
|
+
* reaches the dispatcher can read the drafts the preview renders, but never
|
|
548
|
+
* edit or publish.
|
|
549
|
+
*/
|
|
550
|
+
const inProcessRequests = new WeakSet();
|
|
551
|
+
const IN_PROCESS_READS = new Set(["/draft/pages", "/draft/slugs", "/draft/site-config"]);
|
|
541
552
|
const handler = async function handler(request) {
|
|
542
553
|
const url = new URL(request.url);
|
|
543
|
-
|
|
554
|
+
const inProcess = inProcessRequests.has(request);
|
|
555
|
+
// An in-process URL is synthetic; recording it would mislead every HTTP reader.
|
|
556
|
+
if (!inProcess)
|
|
557
|
+
observeLibraryMount(`${url.origin}${basePath}`);
|
|
544
558
|
const path = stripBasePath(url.pathname, basePath);
|
|
545
559
|
const cors = corsHeadersFor(request, config);
|
|
546
560
|
if (request.method === "OPTIONS") {
|
|
@@ -566,9 +580,12 @@ export function createOrchestrator(config = {}) {
|
|
|
566
580
|
* (the /auth exchange itself, and image reads an <img> tag cannot
|
|
567
581
|
* authenticate) pass through inside checkAuth.
|
|
568
582
|
*/
|
|
569
|
-
const
|
|
570
|
-
if (
|
|
571
|
-
|
|
583
|
+
const trustedRead = inProcess && request.method === "GET" && IN_PROCESS_READS.has(path);
|
|
584
|
+
if (!trustedRead) {
|
|
585
|
+
const gate = await checkAuth({ request, path, auth: config.auth, cors, log: gateLogger });
|
|
586
|
+
if (gate.response)
|
|
587
|
+
return gate.response;
|
|
588
|
+
}
|
|
572
589
|
if (request.method === "GET" && path === "/auth/status") {
|
|
573
590
|
/*
|
|
574
591
|
* `gateEnabled` answers one question for the editor's PasswordGate: "do I
|
|
@@ -2647,7 +2664,13 @@ export function createOrchestrator(config = {}) {
|
|
|
2647
2664
|
"Use the Fastify orchestrator at apps/orchestrator for the full surface (sites, the session directory, the agent surface, etc.)."
|
|
2648
2665
|
}, { status: 405, cors });
|
|
2649
2666
|
};
|
|
2667
|
+
const dispatchInProcess = (request) => {
|
|
2668
|
+
inProcessRequests.add(request);
|
|
2669
|
+
return handler(request);
|
|
2670
|
+
};
|
|
2671
|
+
registerLibraryDispatch(basePath, dispatchInProcess);
|
|
2650
2672
|
handler.dispose = async () => {
|
|
2673
|
+
clearLibraryDispatch(dispatchInProcess);
|
|
2651
2674
|
if (!runtimePromise)
|
|
2652
2675
|
return;
|
|
2653
2676
|
try {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export declare const LIBRARY_MOUNT_KEY = "__avocado_library_mount__";
|
|
2
|
+
export type LibraryDispatch = (request: Request) => Promise<Response>;
|
|
2
3
|
/** Called at construction, from `previewUrl` + `basePath`. */
|
|
3
4
|
export declare function declareLibraryMount(url: string): void;
|
|
4
5
|
/** Called on each request, from the URL the runtime actually received. */
|
|
5
6
|
export declare function observeLibraryMount(url: string): void;
|
|
6
7
|
export declare function getLibraryMount(): string | null;
|
|
8
|
+
/** Called at construction: this handler answers in-process draft reads. */
|
|
9
|
+
export declare function registerLibraryDispatch(basePath: string, dispatch: LibraryDispatch): void;
|
|
10
|
+
/** Called on dispose, and only clears the slot if it is still this handler's. */
|
|
11
|
+
export declare function clearLibraryDispatch(dispatch: LibraryDispatch): void;
|
|
@@ -43,3 +43,17 @@ export function getLibraryMount() {
|
|
|
43
43
|
const s = slot();
|
|
44
44
|
return s.observed ?? s.declared ?? null;
|
|
45
45
|
}
|
|
46
|
+
/** Called at construction: this handler answers in-process draft reads. */
|
|
47
|
+
export function registerLibraryDispatch(basePath, dispatch) {
|
|
48
|
+
const s = slot();
|
|
49
|
+
s.basePath = basePath.replace(/\/+$/, "");
|
|
50
|
+
s.dispatch = dispatch;
|
|
51
|
+
}
|
|
52
|
+
/** Called on dispose, and only clears the slot if it is still this handler's. */
|
|
53
|
+
export function clearLibraryDispatch(dispatch) {
|
|
54
|
+
const s = slot();
|
|
55
|
+
if (s.dispatch !== dispatch)
|
|
56
|
+
return;
|
|
57
|
+
delete s.dispatch;
|
|
58
|
+
delete s.basePath;
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avocadostudio-ai/orchestrator-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package.json": "./package.json",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"openai": "^4.87.1",
|
|
23
23
|
"sharp": "^0.35.4",
|
|
24
24
|
"zod": "^4.3.6",
|
|
25
|
-
"@avocadostudio-ai/migration-sdk": "^0.
|
|
26
|
-
"@avocadostudio-ai/shared": "^0.
|
|
25
|
+
"@avocadostudio-ai/migration-sdk": "^0.27.0",
|
|
26
|
+
"@avocadostudio-ai/shared": "^0.27.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
|