@avocadostudio-ai/site-sdk 0.12.1 → 0.13.1
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.
|
@@ -43,6 +43,16 @@ export interface EditorApiHandlerConfig {
|
|
|
43
43
|
* request.
|
|
44
44
|
*/
|
|
45
45
|
blockTypes?: readonly string[];
|
|
46
|
+
/**
|
|
47
|
+
* Editor origins this app allows, for hosts that configure Avocado in code
|
|
48
|
+
* rather than through `EDITOR_CORS_ORIGINS`.
|
|
49
|
+
*
|
|
50
|
+
* Additive to the environment, never a replacement for it. See
|
|
51
|
+
* `declareEditorCorsOrigins`: the Astro integration takes this list in
|
|
52
|
+
* `astro.config.ts` because it also decides the `postMessage` target, and a
|
|
53
|
+
* site that named its editor there was still refused by CORS in production.
|
|
54
|
+
*/
|
|
55
|
+
editorOrigins?: readonly string[];
|
|
46
56
|
onPublish?: OnPublishFn;
|
|
47
57
|
/** Secret token required for publish requests. Checked against x-publish-token header. */
|
|
48
58
|
publishSecret?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createDraftEnableHandlerCore, createDraftDisableHandlerCore } from "./draft-routes-core.js";
|
|
2
2
|
import { createBlocksHandler, createPagesHandler, createPublishHandler } from "./editor-routes.js";
|
|
3
|
-
import { applyEditorCors } from "./editor-cors.js";
|
|
3
|
+
import { applyEditorCors, declareEditorCorsOrigins } from "./editor-cors.js";
|
|
4
4
|
import { checkIntegrationOnce } from "./integration-check.js";
|
|
5
5
|
import { buildBlockManifest } from "./editor-manifest.js";
|
|
6
6
|
import { declareBlockCatalogue } from "@avocadostudio-ai/shared";
|
|
@@ -21,6 +21,8 @@ import { declareBlockCatalogue } from "@avocadostudio-ai/shared";
|
|
|
21
21
|
* - `/api/editor/publish` → publish content (POST)
|
|
22
22
|
*/
|
|
23
23
|
export function createEditorApiHandlerCore(config) {
|
|
24
|
+
if (config.editorOrigins?.length)
|
|
25
|
+
declareEditorCorsOrigins(config.editorOrigins);
|
|
24
26
|
const draftEnable = createDraftEnableHandlerCore(config.draftAdapter);
|
|
25
27
|
const draftDisable = createDraftDisableHandlerCore(config.draftAdapter);
|
|
26
28
|
const basePath = (config.basePath ?? "/api/editor").replace(/\/+$/, "");
|
package/dist/editor-cors.d.ts
CHANGED
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
* site's draft content out of its own browser. Now the development default is
|
|
10
10
|
* only assumed in development, and a deployment says what it allows.
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Origins the *host application* names in its own configuration, as opposed to
|
|
14
|
+
* in the environment.
|
|
15
|
+
*
|
|
16
|
+
* `EDITOR_CORS_ORIGINS` assumes the deployment configures Avocado through env
|
|
17
|
+
* vars, which is true of Next and false of Astro: there the editor origins are
|
|
18
|
+
* an argument to the integration in `astro.config.ts`, because that same list
|
|
19
|
+
* decides the `postMessage` target and which frame may drive inline edits. A
|
|
20
|
+
* site that had correctly named its editor in the one place the integration
|
|
21
|
+
* asks for it still got no `Access-Control-Allow-Origin`, and only in
|
|
22
|
+
* production — in development the loopback defaults below cover it, so the
|
|
23
|
+
* whole class is invisible until deploy.
|
|
24
|
+
*
|
|
25
|
+
* Additive on purpose: env still works, still wins nothing and loses nothing,
|
|
26
|
+
* and a host that declares the same origin twice is not a conflict.
|
|
27
|
+
*/
|
|
28
|
+
export declare function declareEditorCorsOrigins(origins: readonly string[]): void;
|
|
12
29
|
export declare function getEditorCorsOrigins(): Set<string>;
|
|
13
30
|
/** Test seam — the cache is a module global, and env changes must be able to take effect. */
|
|
14
31
|
export declare function resetEditorCorsOrigins(): void;
|
package/dist/editor-cors.js
CHANGED
|
@@ -27,6 +27,35 @@ import { withLoopbackSpellings, editorAllowHeaders } from "@avocadostudio-ai/sha
|
|
|
27
27
|
*/
|
|
28
28
|
const DEV_EDITOR_ORIGINS = ["http://localhost:4100", "http://127.0.0.1:4100"];
|
|
29
29
|
let cachedOrigins;
|
|
30
|
+
const declaredOrigins = [];
|
|
31
|
+
/**
|
|
32
|
+
* Origins the *host application* names in its own configuration, as opposed to
|
|
33
|
+
* in the environment.
|
|
34
|
+
*
|
|
35
|
+
* `EDITOR_CORS_ORIGINS` assumes the deployment configures Avocado through env
|
|
36
|
+
* vars, which is true of Next and false of Astro: there the editor origins are
|
|
37
|
+
* an argument to the integration in `astro.config.ts`, because that same list
|
|
38
|
+
* decides the `postMessage` target and which frame may drive inline edits. A
|
|
39
|
+
* site that had correctly named its editor in the one place the integration
|
|
40
|
+
* asks for it still got no `Access-Control-Allow-Origin`, and only in
|
|
41
|
+
* production — in development the loopback defaults below cover it, so the
|
|
42
|
+
* whole class is invisible until deploy.
|
|
43
|
+
*
|
|
44
|
+
* Additive on purpose: env still works, still wins nothing and loses nothing,
|
|
45
|
+
* and a host that declares the same origin twice is not a conflict.
|
|
46
|
+
*/
|
|
47
|
+
export function declareEditorCorsOrigins(origins) {
|
|
48
|
+
let added = false;
|
|
49
|
+
for (const origin of origins) {
|
|
50
|
+
const normalized = origin.trim().replace(/\/+$/, "");
|
|
51
|
+
if (!normalized || declaredOrigins.includes(normalized))
|
|
52
|
+
continue;
|
|
53
|
+
declaredOrigins.push(normalized);
|
|
54
|
+
added = true;
|
|
55
|
+
}
|
|
56
|
+
if (added)
|
|
57
|
+
cachedOrigins = undefined;
|
|
58
|
+
}
|
|
30
59
|
function parseOrigins(value) {
|
|
31
60
|
return (value ?? "")
|
|
32
61
|
.split(",")
|
|
@@ -61,12 +90,13 @@ export function getEditorCorsOrigins() {
|
|
|
61
90
|
* `editor-origin-parity.test.ts` now asserts the two produce the same set,
|
|
62
91
|
* so the next person to change one is told about the other.
|
|
63
92
|
*/
|
|
64
|
-
cachedOrigins = new Set(withLoopbackSpellings([...defaults, ...declaredEditor, ...configured]));
|
|
93
|
+
cachedOrigins = new Set(withLoopbackSpellings([...defaults, ...declaredEditor, ...configured, ...declaredOrigins]));
|
|
65
94
|
return cachedOrigins;
|
|
66
95
|
}
|
|
67
96
|
/** Test seam — the cache is a module global, and env changes must be able to take effect. */
|
|
68
97
|
export function resetEditorCorsOrigins() {
|
|
69
98
|
cachedOrigins = undefined;
|
|
99
|
+
declaredOrigins.length = 0;
|
|
70
100
|
}
|
|
71
101
|
export function applyEditorCors(response, requestOrigin) {
|
|
72
102
|
const vary = response.headers.get("Vary") ?? "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avocadostudio-ai/site-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -147,17 +147,17 @@
|
|
|
147
147
|
],
|
|
148
148
|
"dependencies": {
|
|
149
149
|
"zod": "^4.3.6",
|
|
150
|
-
"@avocadostudio-ai/blocks": "^0.
|
|
151
|
-
"@avocadostudio-ai/
|
|
152
|
-
"@avocadostudio-ai/
|
|
153
|
-
"@avocadostudio-ai/
|
|
150
|
+
"@avocadostudio-ai/blocks": "^0.13.1",
|
|
151
|
+
"@avocadostudio-ai/richtext": "^0.13.1",
|
|
152
|
+
"@avocadostudio-ai/shared": "^0.13.1",
|
|
153
|
+
"@avocadostudio-ai/preview-adapter": "^0.13.1"
|
|
154
154
|
},
|
|
155
155
|
"peerDependencies": {
|
|
156
156
|
"next": ">=15.0.0",
|
|
157
157
|
"react": ">=19.0.0",
|
|
158
158
|
"react-dom": ">=19.0.0",
|
|
159
159
|
"better-sqlite3": ">=12.0.0",
|
|
160
|
-
"@avocadostudio-ai/orchestrator-core": "^0.
|
|
160
|
+
"@avocadostudio-ai/orchestrator-core": "^0.13.1"
|
|
161
161
|
},
|
|
162
162
|
"peerDependenciesMeta": {
|
|
163
163
|
"@avocadostudio-ai/orchestrator-core": {
|