@avocadostudio-ai/astro 0.8.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/LICENSE +201 -0
- package/README.md +126 -0
- package/dist/bridge.d.ts +30 -0
- package/dist/bridge.js +125 -0
- package/dist/draft-adapter.d.ts +19 -0
- package/dist/draft-adapter.js +67 -0
- package/dist/draft-cookie.d.ts +26 -0
- package/dist/draft-cookie.js +86 -0
- package/dist/editor-api-route.d.ts +2 -0
- package/dist/editor-api-route.js +20 -0
- package/dist/editor-api.d.ts +30 -0
- package/dist/editor-api.js +36 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +147 -0
- package/dist/markers.d.ts +31 -0
- package/dist/markers.js +49 -0
- package/dist/middleware-entry.d.ts +1 -0
- package/dist/middleware-entry.js +12 -0
- package/dist/middleware.d.ts +22 -0
- package/dist/middleware.js +55 -0
- package/dist/runtime.d.ts +48 -0
- package/dist/runtime.js +73 -0
- package/package.json +91 -0
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { decideEditorRewrite } from "@avocadostudio-ai/site-sdk/proxy/core";
|
|
2
|
+
import { ASTRO_DRAFT_COOKIE, draftSecret, verifyDraftCookie } from "./draft-cookie.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve what a request means, for Astro's middleware and for anything else
|
|
5
|
+
* holding a `Request`.
|
|
6
|
+
*
|
|
7
|
+
* Two things can mark a request as the editor's: the `__editor=1` parameter the
|
|
8
|
+
* editor puts on the iframe URL, and the signed draft cookie that keeps
|
|
9
|
+
* navigation *inside* the iframe in preview. The parameter alone authorizes
|
|
10
|
+
* nothing on its own — it is a routing hint with no secret in it — so a request
|
|
11
|
+
* carrying only the parameter is treated as an editor render but the session it
|
|
12
|
+
* reports comes from the URL, and the content it may see is decided by
|
|
13
|
+
* `/api/editor/draft` having minted a cookie or by a valid `secret`. This
|
|
14
|
+
* mirrors `resolveDraftContextCore`, deliberately.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveEditorRequest(request, options) {
|
|
17
|
+
const url = new URL(request.url);
|
|
18
|
+
const cookies = parseCookies(request.headers.get("cookie"));
|
|
19
|
+
const decision = decideEditorRewrite({ pathname: url.pathname, searchParams: url.searchParams, hasCookie: (name) => name in cookies }, { draftCookie: ASTRO_DRAFT_COOKIE });
|
|
20
|
+
if (decision.kind === "pass")
|
|
21
|
+
return { isEditor: false };
|
|
22
|
+
const verified = verifyDraftCookie(cookies[ASTRO_DRAFT_COOKIE], options?.secret ?? draftSecret());
|
|
23
|
+
const session = url.searchParams.get("session")?.trim() || verified?.session || options?.session || "dev";
|
|
24
|
+
const siteId = url.searchParams.get("siteId")?.trim() || verified?.siteId || options?.siteId || process.env.AVOCADO_SITE_ID || "";
|
|
25
|
+
const editorOrigin = resolveEditorOrigin(url.searchParams.get("editorOrigin"), options?.editorOrigins);
|
|
26
|
+
const params = new URLSearchParams({ __editor: "1", session, siteId });
|
|
27
|
+
if (editorOrigin)
|
|
28
|
+
params.set("editorOrigin", editorOrigin);
|
|
29
|
+
const secret = url.searchParams.get("secret");
|
|
30
|
+
/*
|
|
31
|
+
* The secret is carried forward because it is what authorizes a render when
|
|
32
|
+
* the cookie cannot be: the editor renders the site in a cross-origin iframe,
|
|
33
|
+
* and third-party cookies are frequently blocked outright. Dropping it from
|
|
34
|
+
* in-preview links makes every navigation after the first one render the
|
|
35
|
+
* published page, in exactly the browsers where that is hardest to reproduce.
|
|
36
|
+
*/
|
|
37
|
+
if (secret)
|
|
38
|
+
params.set("secret", secret);
|
|
39
|
+
return { isEditor: true, session, siteId, editorOrigin, editorQuery: `?${params.toString()}` };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The editor origin becomes a `postMessage` target and the frame allowed to
|
|
43
|
+
* drive inline edits, so it cannot be whatever the URL says. A candidate counts
|
|
44
|
+
* only when the operator listed it.
|
|
45
|
+
*/
|
|
46
|
+
function resolveEditorOrigin(candidate, allowed) {
|
|
47
|
+
const list = allowed?.map((o) => o.replace(/\/+$/, "")) ?? [];
|
|
48
|
+
const fallback = list[0] ?? (process.env.NODE_ENV !== "production" ? "http://localhost:4100" : "");
|
|
49
|
+
if (!candidate)
|
|
50
|
+
return fallback;
|
|
51
|
+
try {
|
|
52
|
+
const origin = new URL(decodeURIComponent(candidate)).origin;
|
|
53
|
+
if (list.length === 0)
|
|
54
|
+
return process.env.NODE_ENV !== "production" ? origin : fallback;
|
|
55
|
+
return list.includes(origin) ? origin : fallback;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return fallback;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function parseCookies(header) {
|
|
62
|
+
const out = {};
|
|
63
|
+
if (!header)
|
|
64
|
+
return out;
|
|
65
|
+
for (const part of header.split(";")) {
|
|
66
|
+
const eq = part.indexOf("=");
|
|
67
|
+
if (eq < 0)
|
|
68
|
+
continue;
|
|
69
|
+
out[part.slice(0, eq).trim()] = decodeURIComponent(part.slice(eq + 1).trim());
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
export { ASTRO_DRAFT_COOKIE } from "./draft-cookie.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@avocadostudio-ai/astro",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./package.json": "./package.json",
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./middleware": {
|
|
15
|
+
"types": "./dist/middleware.d.ts",
|
|
16
|
+
"import": "./dist/middleware.js",
|
|
17
|
+
"default": "./dist/middleware.js"
|
|
18
|
+
},
|
|
19
|
+
"./middleware-entry": {
|
|
20
|
+
"types": "./dist/middleware-entry.d.ts",
|
|
21
|
+
"import": "./dist/middleware-entry.js",
|
|
22
|
+
"default": "./dist/middleware-entry.js"
|
|
23
|
+
},
|
|
24
|
+
"./editor-api": {
|
|
25
|
+
"types": "./dist/editor-api.d.ts",
|
|
26
|
+
"import": "./dist/editor-api.js",
|
|
27
|
+
"default": "./dist/editor-api.js"
|
|
28
|
+
},
|
|
29
|
+
"./editor-api-route": {
|
|
30
|
+
"types": "./dist/editor-api-route.d.ts",
|
|
31
|
+
"import": "./dist/editor-api-route.js",
|
|
32
|
+
"default": "./dist/editor-api-route.js"
|
|
33
|
+
},
|
|
34
|
+
"./runtime": {
|
|
35
|
+
"types": "./dist/runtime.d.ts",
|
|
36
|
+
"import": "./dist/runtime.js",
|
|
37
|
+
"default": "./dist/runtime.js"
|
|
38
|
+
},
|
|
39
|
+
"./markers": {
|
|
40
|
+
"types": "./dist/markers.d.ts",
|
|
41
|
+
"import": "./dist/markers.js",
|
|
42
|
+
"default": "./dist/markers.js"
|
|
43
|
+
},
|
|
44
|
+
"./bridge": {
|
|
45
|
+
"types": "./dist/bridge.d.ts",
|
|
46
|
+
"import": "./dist/bridge.js",
|
|
47
|
+
"default": "./dist/bridge.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"registry": "https://registry.npmjs.org",
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"dist"
|
|
56
|
+
],
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@avocadostudio-ai/shared": "^0.8.0",
|
|
59
|
+
"@avocadostudio-ai/preview-adapter": "^0.8.0",
|
|
60
|
+
"@avocadostudio-ai/site-sdk": "^0.8.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"astro": ">=5.0.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/node": "^22.13.10",
|
|
67
|
+
"astro": "^7.3.1",
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"typescript": "^5.7.3"
|
|
70
|
+
},
|
|
71
|
+
"description": "Astro integration for Avocado Studio — editor API, draft preview, and the live-preview bridge, with no React",
|
|
72
|
+
"keywords": [
|
|
73
|
+
"avocado",
|
|
74
|
+
"avocado-studio",
|
|
75
|
+
"astro",
|
|
76
|
+
"astro-integration",
|
|
77
|
+
"visual-editing",
|
|
78
|
+
"live-preview",
|
|
79
|
+
"cms"
|
|
80
|
+
],
|
|
81
|
+
"license": "Apache-2.0",
|
|
82
|
+
"homepage": "https://docs.avocadostudio.dev",
|
|
83
|
+
"bugs": {
|
|
84
|
+
"url": "https://docs.avocadostudio.dev"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsc -p tsconfig.build.json",
|
|
88
|
+
"typecheck": "tsc --noEmit",
|
|
89
|
+
"test": "NODE_ENV=test node ../../scripts/run-tests.mjs"
|
|
90
|
+
}
|
|
91
|
+
}
|