@cmssy/react 0.1.7 → 0.1.9
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/client.cjs +96 -0
- package/dist/client.d.cts +27 -3
- package/dist/client.d.ts +27 -3
- package/dist/client.js +96 -2
- package/dist/index.cjs +64 -20
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +64 -21
- package/dist/{registry-BaFQ2k7r.d.cts → registry-e3O4s_bN.d.cts} +23 -1
- package/dist/{registry-BaFQ2k7r.d.ts → registry-e3O4s_bN.d.ts} +23 -1
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -747,9 +747,105 @@ function CmssyLazyLayout({ load, ...props }) {
|
|
|
747
747
|
if (!blocks) return null;
|
|
748
748
|
return /* @__PURE__ */ jsxRuntime.jsx(CmssyEditableLayout, { ...props, blocks });
|
|
749
749
|
}
|
|
750
|
+
var CmssyAuthContext = react.createContext(null);
|
|
751
|
+
function CmssyAuthProvider({
|
|
752
|
+
children,
|
|
753
|
+
basePath = "/api/cmssy/auth",
|
|
754
|
+
initialUser
|
|
755
|
+
}) {
|
|
756
|
+
const seeded = initialUser !== void 0;
|
|
757
|
+
const [user, setUser] = react.useState(initialUser ?? null);
|
|
758
|
+
const [loading, setLoading] = react.useState(!seeded);
|
|
759
|
+
const generation = react.useRef(0);
|
|
760
|
+
const base = react.useMemo(() => basePath.replace(/\/+$/, ""), [basePath]);
|
|
761
|
+
const commitUser = react.useCallback((next) => {
|
|
762
|
+
generation.current += 1;
|
|
763
|
+
setUser(next);
|
|
764
|
+
}, []);
|
|
765
|
+
const fetchUser = react.useCallback(async () => {
|
|
766
|
+
try {
|
|
767
|
+
const res = await fetch(`${base}/me`, {
|
|
768
|
+
credentials: "same-origin",
|
|
769
|
+
cache: "no-store"
|
|
770
|
+
});
|
|
771
|
+
const data = await res.json();
|
|
772
|
+
return data.user ?? null;
|
|
773
|
+
} catch {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
}, [base]);
|
|
777
|
+
react.useEffect(() => {
|
|
778
|
+
if (seeded) return;
|
|
779
|
+
const gen = generation.current;
|
|
780
|
+
void (async () => {
|
|
781
|
+
const next = await fetchUser();
|
|
782
|
+
if (gen === generation.current) {
|
|
783
|
+
setUser(next);
|
|
784
|
+
setLoading(false);
|
|
785
|
+
}
|
|
786
|
+
})();
|
|
787
|
+
}, [fetchUser, seeded]);
|
|
788
|
+
const postAction = react.useCallback(
|
|
789
|
+
async (action, body) => {
|
|
790
|
+
const res = await fetch(`${base}/${action}`, {
|
|
791
|
+
method: "POST",
|
|
792
|
+
credentials: "same-origin",
|
|
793
|
+
headers: { "content-type": "application/json" },
|
|
794
|
+
body: JSON.stringify(body)
|
|
795
|
+
});
|
|
796
|
+
return await res.json();
|
|
797
|
+
},
|
|
798
|
+
[base]
|
|
799
|
+
);
|
|
800
|
+
const signIn = react.useCallback(
|
|
801
|
+
async (identity, password) => {
|
|
802
|
+
const data = await postAction("sign-in", { identity, password });
|
|
803
|
+
if (data.ok && data.user) commitUser(data.user);
|
|
804
|
+
return { ok: Boolean(data.ok), message: data.message };
|
|
805
|
+
},
|
|
806
|
+
[postAction, commitUser]
|
|
807
|
+
);
|
|
808
|
+
const register = react.useCallback(
|
|
809
|
+
async (identity, password, fields) => {
|
|
810
|
+
const data = await postAction("register", {
|
|
811
|
+
identity,
|
|
812
|
+
password,
|
|
813
|
+
fields: fields ?? {}
|
|
814
|
+
});
|
|
815
|
+
return { ok: Boolean(data.ok), message: data.message };
|
|
816
|
+
},
|
|
817
|
+
[postAction]
|
|
818
|
+
);
|
|
819
|
+
const signOut = react.useCallback(async () => {
|
|
820
|
+
try {
|
|
821
|
+
await postAction("sign-out", {});
|
|
822
|
+
} finally {
|
|
823
|
+
commitUser(null);
|
|
824
|
+
}
|
|
825
|
+
}, [postAction, commitUser]);
|
|
826
|
+
const refresh = react.useCallback(async () => {
|
|
827
|
+
const gen = generation.current;
|
|
828
|
+
const next = await fetchUser();
|
|
829
|
+
if (gen === generation.current) setUser(next);
|
|
830
|
+
}, [fetchUser]);
|
|
831
|
+
const value = react.useMemo(
|
|
832
|
+
() => ({ user, loading, signIn, register, signOut, refresh }),
|
|
833
|
+
[user, loading, signIn, register, signOut, refresh]
|
|
834
|
+
);
|
|
835
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CmssyAuthContext.Provider, { value, children });
|
|
836
|
+
}
|
|
837
|
+
function useCmssyUser() {
|
|
838
|
+
const ctx = react.useContext(CmssyAuthContext);
|
|
839
|
+
if (!ctx) {
|
|
840
|
+
throw new Error("useCmssyUser must be used within <CmssyAuthProvider>");
|
|
841
|
+
}
|
|
842
|
+
return ctx;
|
|
843
|
+
}
|
|
750
844
|
|
|
845
|
+
exports.CmssyAuthProvider = CmssyAuthProvider;
|
|
751
846
|
exports.CmssyEditableLayout = CmssyEditableLayout;
|
|
752
847
|
exports.CmssyEditablePage = CmssyEditablePage;
|
|
753
848
|
exports.CmssyLazyEditor = CmssyLazyEditor;
|
|
754
849
|
exports.CmssyLazyLayout = CmssyLazyLayout;
|
|
850
|
+
exports.useCmssyUser = useCmssyUser;
|
|
755
851
|
exports.useEditBridge = useEditBridge;
|
package/dist/client.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-
|
|
3
|
-
import 'react';
|
|
2
|
+
import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-e3O4s_bN.cjs';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
interface EditBridgeConfig {
|
|
6
6
|
editorOrigin: string;
|
|
@@ -80,4 +80,28 @@ interface CmssyLazyLayoutProps {
|
|
|
80
80
|
}
|
|
81
81
|
declare function CmssyLazyLayout({ load, ...props }: CmssyLazyLayoutProps): react_jsx_runtime.JSX.Element | null;
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
interface CmssyAuthUser {
|
|
84
|
+
recordId: string;
|
|
85
|
+
email: string;
|
|
86
|
+
}
|
|
87
|
+
interface CmssyAuthActionResult {
|
|
88
|
+
ok: boolean;
|
|
89
|
+
message?: string;
|
|
90
|
+
}
|
|
91
|
+
interface CmssyAuthState {
|
|
92
|
+
user: CmssyAuthUser | null;
|
|
93
|
+
loading: boolean;
|
|
94
|
+
signIn(identity: string, password: string): Promise<CmssyAuthActionResult>;
|
|
95
|
+
register(identity: string, password: string, fields?: Record<string, unknown>): Promise<CmssyAuthActionResult>;
|
|
96
|
+
signOut(): Promise<void>;
|
|
97
|
+
refresh(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
interface CmssyAuthProviderProps {
|
|
100
|
+
children: ReactNode;
|
|
101
|
+
basePath?: string;
|
|
102
|
+
initialUser?: CmssyAuthUser | null;
|
|
103
|
+
}
|
|
104
|
+
declare function CmssyAuthProvider({ children, basePath, initialUser, }: CmssyAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function useCmssyUser(): CmssyAuthState;
|
|
106
|
+
|
|
107
|
+
export { type CmssyAuthActionResult, CmssyAuthProvider, type CmssyAuthProviderProps, type CmssyAuthState, type CmssyAuthUser, CmssyEditableLayout, type CmssyEditableLayoutProps, CmssyEditablePage, type CmssyEditablePageProps, CmssyLazyEditor, type CmssyLazyEditorProps, CmssyLazyLayout, type CmssyLazyLayoutProps, type EditBridgeConfig, type EditBridgeState, type PatchMap, useCmssyUser, useEditBridge };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-
|
|
3
|
-
import 'react';
|
|
2
|
+
import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-e3O4s_bN.js';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
interface EditBridgeConfig {
|
|
6
6
|
editorOrigin: string;
|
|
@@ -80,4 +80,28 @@ interface CmssyLazyLayoutProps {
|
|
|
80
80
|
}
|
|
81
81
|
declare function CmssyLazyLayout({ load, ...props }: CmssyLazyLayoutProps): react_jsx_runtime.JSX.Element | null;
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
interface CmssyAuthUser {
|
|
84
|
+
recordId: string;
|
|
85
|
+
email: string;
|
|
86
|
+
}
|
|
87
|
+
interface CmssyAuthActionResult {
|
|
88
|
+
ok: boolean;
|
|
89
|
+
message?: string;
|
|
90
|
+
}
|
|
91
|
+
interface CmssyAuthState {
|
|
92
|
+
user: CmssyAuthUser | null;
|
|
93
|
+
loading: boolean;
|
|
94
|
+
signIn(identity: string, password: string): Promise<CmssyAuthActionResult>;
|
|
95
|
+
register(identity: string, password: string, fields?: Record<string, unknown>): Promise<CmssyAuthActionResult>;
|
|
96
|
+
signOut(): Promise<void>;
|
|
97
|
+
refresh(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
interface CmssyAuthProviderProps {
|
|
100
|
+
children: ReactNode;
|
|
101
|
+
basePath?: string;
|
|
102
|
+
initialUser?: CmssyAuthUser | null;
|
|
103
|
+
}
|
|
104
|
+
declare function CmssyAuthProvider({ children, basePath, initialUser, }: CmssyAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function useCmssyUser(): CmssyAuthState;
|
|
106
|
+
|
|
107
|
+
export { type CmssyAuthActionResult, CmssyAuthProvider, type CmssyAuthProviderProps, type CmssyAuthState, type CmssyAuthUser, CmssyEditableLayout, type CmssyEditableLayoutProps, CmssyEditablePage, type CmssyEditablePageProps, CmssyLazyEditor, type CmssyLazyEditorProps, CmssyLazyLayout, type CmssyLazyLayoutProps, type EditBridgeConfig, type EditBridgeState, type PatchMap, useCmssyUser, useEditBridge };
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useState, useRef, useEffect, useMemo, createElement } from 'react';
|
|
2
|
+
import { createContext, useState, useRef, useEffect, useMemo, useCallback, useContext, createElement } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
// src/registry.ts
|
|
@@ -745,5 +745,99 @@ function CmssyLazyLayout({ load, ...props }) {
|
|
|
745
745
|
if (!blocks) return null;
|
|
746
746
|
return /* @__PURE__ */ jsx(CmssyEditableLayout, { ...props, blocks });
|
|
747
747
|
}
|
|
748
|
+
var CmssyAuthContext = createContext(null);
|
|
749
|
+
function CmssyAuthProvider({
|
|
750
|
+
children,
|
|
751
|
+
basePath = "/api/cmssy/auth",
|
|
752
|
+
initialUser
|
|
753
|
+
}) {
|
|
754
|
+
const seeded = initialUser !== void 0;
|
|
755
|
+
const [user, setUser] = useState(initialUser ?? null);
|
|
756
|
+
const [loading, setLoading] = useState(!seeded);
|
|
757
|
+
const generation = useRef(0);
|
|
758
|
+
const base = useMemo(() => basePath.replace(/\/+$/, ""), [basePath]);
|
|
759
|
+
const commitUser = useCallback((next) => {
|
|
760
|
+
generation.current += 1;
|
|
761
|
+
setUser(next);
|
|
762
|
+
}, []);
|
|
763
|
+
const fetchUser = useCallback(async () => {
|
|
764
|
+
try {
|
|
765
|
+
const res = await fetch(`${base}/me`, {
|
|
766
|
+
credentials: "same-origin",
|
|
767
|
+
cache: "no-store"
|
|
768
|
+
});
|
|
769
|
+
const data = await res.json();
|
|
770
|
+
return data.user ?? null;
|
|
771
|
+
} catch {
|
|
772
|
+
return null;
|
|
773
|
+
}
|
|
774
|
+
}, [base]);
|
|
775
|
+
useEffect(() => {
|
|
776
|
+
if (seeded) return;
|
|
777
|
+
const gen = generation.current;
|
|
778
|
+
void (async () => {
|
|
779
|
+
const next = await fetchUser();
|
|
780
|
+
if (gen === generation.current) {
|
|
781
|
+
setUser(next);
|
|
782
|
+
setLoading(false);
|
|
783
|
+
}
|
|
784
|
+
})();
|
|
785
|
+
}, [fetchUser, seeded]);
|
|
786
|
+
const postAction = useCallback(
|
|
787
|
+
async (action, body) => {
|
|
788
|
+
const res = await fetch(`${base}/${action}`, {
|
|
789
|
+
method: "POST",
|
|
790
|
+
credentials: "same-origin",
|
|
791
|
+
headers: { "content-type": "application/json" },
|
|
792
|
+
body: JSON.stringify(body)
|
|
793
|
+
});
|
|
794
|
+
return await res.json();
|
|
795
|
+
},
|
|
796
|
+
[base]
|
|
797
|
+
);
|
|
798
|
+
const signIn = useCallback(
|
|
799
|
+
async (identity, password) => {
|
|
800
|
+
const data = await postAction("sign-in", { identity, password });
|
|
801
|
+
if (data.ok && data.user) commitUser(data.user);
|
|
802
|
+
return { ok: Boolean(data.ok), message: data.message };
|
|
803
|
+
},
|
|
804
|
+
[postAction, commitUser]
|
|
805
|
+
);
|
|
806
|
+
const register = useCallback(
|
|
807
|
+
async (identity, password, fields) => {
|
|
808
|
+
const data = await postAction("register", {
|
|
809
|
+
identity,
|
|
810
|
+
password,
|
|
811
|
+
fields: fields ?? {}
|
|
812
|
+
});
|
|
813
|
+
return { ok: Boolean(data.ok), message: data.message };
|
|
814
|
+
},
|
|
815
|
+
[postAction]
|
|
816
|
+
);
|
|
817
|
+
const signOut = useCallback(async () => {
|
|
818
|
+
try {
|
|
819
|
+
await postAction("sign-out", {});
|
|
820
|
+
} finally {
|
|
821
|
+
commitUser(null);
|
|
822
|
+
}
|
|
823
|
+
}, [postAction, commitUser]);
|
|
824
|
+
const refresh = useCallback(async () => {
|
|
825
|
+
const gen = generation.current;
|
|
826
|
+
const next = await fetchUser();
|
|
827
|
+
if (gen === generation.current) setUser(next);
|
|
828
|
+
}, [fetchUser]);
|
|
829
|
+
const value = useMemo(
|
|
830
|
+
() => ({ user, loading, signIn, register, signOut, refresh }),
|
|
831
|
+
[user, loading, signIn, register, signOut, refresh]
|
|
832
|
+
);
|
|
833
|
+
return /* @__PURE__ */ jsx(CmssyAuthContext.Provider, { value, children });
|
|
834
|
+
}
|
|
835
|
+
function useCmssyUser() {
|
|
836
|
+
const ctx = useContext(CmssyAuthContext);
|
|
837
|
+
if (!ctx) {
|
|
838
|
+
throw new Error("useCmssyUser must be used within <CmssyAuthProvider>");
|
|
839
|
+
}
|
|
840
|
+
return ctx;
|
|
841
|
+
}
|
|
748
842
|
|
|
749
|
-
export { CmssyEditableLayout, CmssyEditablePage, CmssyLazyEditor, CmssyLazyLayout, useEditBridge };
|
|
843
|
+
export { CmssyAuthProvider, CmssyEditableLayout, CmssyEditablePage, CmssyLazyEditor, CmssyLazyLayout, useCmssyUser, useEditBridge };
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,13 @@ function buildBlockMap(blocks) {
|
|
|
35
35
|
for (const block of blocks) map[block.type] = block.component;
|
|
36
36
|
return map;
|
|
37
37
|
}
|
|
38
|
+
function buildLoaderMap(blocks) {
|
|
39
|
+
const map = /* @__PURE__ */ Object.create(null);
|
|
40
|
+
for (const block of blocks) {
|
|
41
|
+
if (block.loader) map[block.type] = block.loader;
|
|
42
|
+
}
|
|
43
|
+
return map;
|
|
44
|
+
}
|
|
38
45
|
function blocksToSchemas(blocks) {
|
|
39
46
|
const out = /* @__PURE__ */ Object.create(null);
|
|
40
47
|
for (const block of blocks) {
|
|
@@ -60,19 +67,6 @@ function blocksToMeta(blocks, defaults = {}) {
|
|
|
60
67
|
return out;
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
// src/components/block-context.ts
|
|
64
|
-
function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
|
|
65
|
-
return {
|
|
66
|
-
locale: {
|
|
67
|
-
current: locale,
|
|
68
|
-
default: defaultLocale,
|
|
69
|
-
enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
|
|
70
|
-
},
|
|
71
|
-
isPreview: isPreview ?? false,
|
|
72
|
-
forms
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
70
|
// src/content/get-block-content.ts
|
|
77
71
|
function isPlainObject(value) {
|
|
78
72
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -96,6 +90,19 @@ function getBlockContentForLanguage(content, locale, defaultLocale = "en", avail
|
|
|
96
90
|
const chosen = localeMap[locale] ?? localeMap[defaultLocale] ?? localeMap[fallbackKey];
|
|
97
91
|
return { ...nonTranslatable, ...chosen };
|
|
98
92
|
}
|
|
93
|
+
|
|
94
|
+
// src/components/block-context.ts
|
|
95
|
+
function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
|
|
96
|
+
return {
|
|
97
|
+
locale: {
|
|
98
|
+
current: locale,
|
|
99
|
+
default: defaultLocale,
|
|
100
|
+
enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
|
|
101
|
+
},
|
|
102
|
+
isPreview: isPreview ?? false,
|
|
103
|
+
forms
|
|
104
|
+
};
|
|
105
|
+
}
|
|
99
106
|
var WARN_CAP = 256;
|
|
100
107
|
var warned = /* @__PURE__ */ new Set();
|
|
101
108
|
function UnknownBlock({ type }) {
|
|
@@ -106,12 +113,14 @@ function UnknownBlock({ type }) {
|
|
|
106
113
|
}
|
|
107
114
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cmssy-unknown-block": type });
|
|
108
115
|
}
|
|
109
|
-
function renderResolvedBlock(block, map, locale, defaultLocale,
|
|
116
|
+
function renderResolvedBlock(block, map, locale, defaultLocale, options = {}) {
|
|
117
|
+
const { context, data, resolvedContent, enabledLocales } = options;
|
|
110
118
|
const Component = Object.hasOwn(map, block.type) ? map[block.type] : void 0;
|
|
111
|
-
const content = getBlockContentForLanguage(
|
|
119
|
+
const content = resolvedContent ?? getBlockContentForLanguage(
|
|
112
120
|
block.content,
|
|
113
121
|
locale,
|
|
114
|
-
defaultLocale
|
|
122
|
+
defaultLocale,
|
|
123
|
+
enabledLocales?.length ? enabledLocales : void 0
|
|
115
124
|
);
|
|
116
125
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
117
126
|
"div",
|
|
@@ -119,12 +128,12 @@ function renderResolvedBlock(block, map, locale, defaultLocale, context) {
|
|
|
119
128
|
"data-block-id": block.id,
|
|
120
129
|
"data-block-type": block.type,
|
|
121
130
|
style: Component ? void 0 : { display: "none" },
|
|
122
|
-
children: Component ? react.createElement(Component, { content, context }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
|
|
131
|
+
children: Component ? react.createElement(Component, { content, context, data }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
|
|
123
132
|
},
|
|
124
133
|
block.id
|
|
125
134
|
);
|
|
126
135
|
}
|
|
127
|
-
function CmssyServerPage({
|
|
136
|
+
async function CmssyServerPage({
|
|
128
137
|
page,
|
|
129
138
|
blocks,
|
|
130
139
|
locale = "en",
|
|
@@ -134,6 +143,7 @@ function CmssyServerPage({
|
|
|
134
143
|
}) {
|
|
135
144
|
if (!page) return null;
|
|
136
145
|
const map = buildBlockMap(blocks);
|
|
146
|
+
const loaderMap = buildLoaderMap(blocks);
|
|
137
147
|
const context = buildBlockContext(
|
|
138
148
|
locale,
|
|
139
149
|
defaultLocale,
|
|
@@ -141,8 +151,38 @@ function CmssyServerPage({
|
|
|
141
151
|
false,
|
|
142
152
|
forms
|
|
143
153
|
);
|
|
154
|
+
const resolved = await Promise.all(
|
|
155
|
+
page.blocks.map(async (block) => {
|
|
156
|
+
const content = getBlockContentForLanguage(
|
|
157
|
+
block.content,
|
|
158
|
+
locale,
|
|
159
|
+
defaultLocale,
|
|
160
|
+
enabledLocales?.length ? enabledLocales : void 0
|
|
161
|
+
);
|
|
162
|
+
const loader = loaderMap[block.type];
|
|
163
|
+
let data;
|
|
164
|
+
if (loader) {
|
|
165
|
+
try {
|
|
166
|
+
data = await loader({ content, context });
|
|
167
|
+
} catch (err) {
|
|
168
|
+
if (typeof console !== "undefined") {
|
|
169
|
+
console.warn(
|
|
170
|
+
`[cmssy] loader for block "${block.type}" (${block.id}) failed`,
|
|
171
|
+
err
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { content, data };
|
|
177
|
+
})
|
|
178
|
+
);
|
|
144
179
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: page.blocks.map(
|
|
145
|
-
(block) => renderResolvedBlock(block, map, locale, defaultLocale,
|
|
180
|
+
(block, i) => renderResolvedBlock(block, map, locale, defaultLocale, {
|
|
181
|
+
context,
|
|
182
|
+
data: resolved[i]?.data,
|
|
183
|
+
resolvedContent: resolved[i]?.content,
|
|
184
|
+
enabledLocales
|
|
185
|
+
})
|
|
146
186
|
) });
|
|
147
187
|
}
|
|
148
188
|
function CmssyServerLayout({
|
|
@@ -159,7 +199,10 @@ function CmssyServerLayout({
|
|
|
159
199
|
const map = buildBlockMap(blocks);
|
|
160
200
|
const context = buildBlockContext(locale, defaultLocale, enabledLocales);
|
|
161
201
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: layoutBlocks.map(
|
|
162
|
-
(block) => renderResolvedBlock(block, map, locale, defaultLocale,
|
|
202
|
+
(block) => renderResolvedBlock(block, map, locale, defaultLocale, {
|
|
203
|
+
context,
|
|
204
|
+
enabledLocales
|
|
205
|
+
})
|
|
163
206
|
) });
|
|
164
207
|
}
|
|
165
208
|
|
|
@@ -642,4 +685,5 @@ exports.parseEditorMessage = parseEditorMessage;
|
|
|
642
685
|
exports.postToEditor = postToEditor;
|
|
643
686
|
exports.resolveForms = resolveForms;
|
|
644
687
|
exports.resolveSiteLocales = resolveSiteLocales;
|
|
688
|
+
exports.resolveWorkspaceId = resolveWorkspaceId;
|
|
645
689
|
exports.splitLocaleFromPath = splitLocaleFromPath;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, e as FetchLike, f as CmssyClientConfig, R as RawBlock, g as BlockMap, h as CmssyBlockContext } from './registry-
|
|
2
|
-
export { a as BlockMeta, i as BlockRect, B as BlockSchema, j as BoundsMessage, k as ClickMessage, l as CmssyBranding, m as CmssyFormField, n as CmssyFormSettings, o as CmssyFormSubmitResponse, p as CmssyLocaleContext, q as CmssyModelDefinition, r as CmssyModelRecord, s as CmssyRecordList, t as CmssySiteConfig, u as FORM_QUERY, v as FetchLikeResponse, w as FetchPageOptions, x as FieldType, M as MODEL_DEFINITIONS_QUERY, y as MODEL_RECORDS_QUERY, P as PROTOCOL_VERSION, z as ParentReadyMessage, D as PatchMessage, G as RawLayoutBlock, H as ReadyMessage, S as SITE_CONFIG_QUERY, I as SUBMIT_FORM_MUTATION, J as SelectMessage, K as SubmitFormInput, L as blocksToMeta, N as blocksToSchemas, O as buildBlockContext, Q as buildBlockMap, T as defineBlock, U as fetchLayouts, V as fetchPage, W as isProtocolCompatible, X as normalizeSlug } from './registry-
|
|
1
|
+
import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, e as FetchLike, f as CmssyClientConfig, R as RawBlock, g as BlockMap, h as CmssyBlockContext } from './registry-e3O4s_bN.cjs';
|
|
2
|
+
export { a as BlockMeta, i as BlockRect, B as BlockSchema, j as BoundsMessage, k as ClickMessage, l as CmssyBranding, m as CmssyFormField, n as CmssyFormSettings, o as CmssyFormSubmitResponse, p as CmssyLocaleContext, q as CmssyModelDefinition, r as CmssyModelRecord, s as CmssyRecordList, t as CmssySiteConfig, u as FORM_QUERY, v as FetchLikeResponse, w as FetchPageOptions, x as FieldType, M as MODEL_DEFINITIONS_QUERY, y as MODEL_RECORDS_QUERY, P as PROTOCOL_VERSION, z as ParentReadyMessage, D as PatchMessage, G as RawLayoutBlock, H as ReadyMessage, S as SITE_CONFIG_QUERY, I as SUBMIT_FORM_MUTATION, J as SelectMessage, K as SubmitFormInput, L as blocksToMeta, N as blocksToSchemas, O as buildBlockContext, Q as buildBlockMap, T as defineBlock, U as fetchLayouts, V as fetchPage, W as isProtocolCompatible, X as normalizeSlug } from './registry-e3O4s_bN.cjs';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
@@ -31,7 +31,12 @@ interface CmssyServerPageProps {
|
|
|
31
31
|
/** Form definitions referenced by page blocks, exposed via context.forms. */
|
|
32
32
|
forms?: Record<string, CmssyFormDefinition>;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Async React Server Component (Next.js App Router / RSC). It runs each block's
|
|
36
|
+
* loader server-side before rendering, so it must be rendered in a server
|
|
37
|
+
* component tree (as `createCmssyPage` does) - not in a client component.
|
|
38
|
+
*/
|
|
39
|
+
declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, forms, }: CmssyServerPageProps): Promise<react_jsx_runtime.JSX.Element | null>;
|
|
35
40
|
|
|
36
41
|
interface CmssyServerLayoutProps {
|
|
37
42
|
groups: CmssyLayoutGroup[];
|
|
@@ -60,6 +65,8 @@ interface GraphqlRequestOptions {
|
|
|
60
65
|
}
|
|
61
66
|
declare function graphqlRequest<T>(config: CmssyClientConfig, query: string, variables: Record<string, unknown>, options?: GraphqlRequestOptions, label?: string): Promise<T>;
|
|
62
67
|
|
|
68
|
+
declare function resolveWorkspaceId(config: CmssyClientConfig, options?: GraphqlRequestOptions): Promise<string>;
|
|
69
|
+
|
|
63
70
|
interface QueryScopedOptions extends GraphqlRequestOptions {
|
|
64
71
|
workspaceId?: string;
|
|
65
72
|
}
|
|
@@ -101,4 +108,4 @@ interface UnknownBlockProps {
|
|
|
101
108
|
}
|
|
102
109
|
declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
|
|
103
110
|
|
|
104
|
-
export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteLocales, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, splitLocaleFromPath };
|
|
111
|
+
export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteLocales, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, e as FetchLike, f as CmssyClientConfig, R as RawBlock, g as BlockMap, h as CmssyBlockContext } from './registry-
|
|
2
|
-
export { a as BlockMeta, i as BlockRect, B as BlockSchema, j as BoundsMessage, k as ClickMessage, l as CmssyBranding, m as CmssyFormField, n as CmssyFormSettings, o as CmssyFormSubmitResponse, p as CmssyLocaleContext, q as CmssyModelDefinition, r as CmssyModelRecord, s as CmssyRecordList, t as CmssySiteConfig, u as FORM_QUERY, v as FetchLikeResponse, w as FetchPageOptions, x as FieldType, M as MODEL_DEFINITIONS_QUERY, y as MODEL_RECORDS_QUERY, P as PROTOCOL_VERSION, z as ParentReadyMessage, D as PatchMessage, G as RawLayoutBlock, H as ReadyMessage, S as SITE_CONFIG_QUERY, I as SUBMIT_FORM_MUTATION, J as SelectMessage, K as SubmitFormInput, L as blocksToMeta, N as blocksToSchemas, O as buildBlockContext, Q as buildBlockMap, T as defineBlock, U as fetchLayouts, V as fetchPage, W as isProtocolCompatible, X as normalizeSlug } from './registry-
|
|
1
|
+
import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, e as FetchLike, f as CmssyClientConfig, R as RawBlock, g as BlockMap, h as CmssyBlockContext } from './registry-e3O4s_bN.js';
|
|
2
|
+
export { a as BlockMeta, i as BlockRect, B as BlockSchema, j as BoundsMessage, k as ClickMessage, l as CmssyBranding, m as CmssyFormField, n as CmssyFormSettings, o as CmssyFormSubmitResponse, p as CmssyLocaleContext, q as CmssyModelDefinition, r as CmssyModelRecord, s as CmssyRecordList, t as CmssySiteConfig, u as FORM_QUERY, v as FetchLikeResponse, w as FetchPageOptions, x as FieldType, M as MODEL_DEFINITIONS_QUERY, y as MODEL_RECORDS_QUERY, P as PROTOCOL_VERSION, z as ParentReadyMessage, D as PatchMessage, G as RawLayoutBlock, H as ReadyMessage, S as SITE_CONFIG_QUERY, I as SUBMIT_FORM_MUTATION, J as SelectMessage, K as SubmitFormInput, L as blocksToMeta, N as blocksToSchemas, O as buildBlockContext, Q as buildBlockMap, T as defineBlock, U as fetchLayouts, V as fetchPage, W as isProtocolCompatible, X as normalizeSlug } from './registry-e3O4s_bN.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
@@ -31,7 +31,12 @@ interface CmssyServerPageProps {
|
|
|
31
31
|
/** Form definitions referenced by page blocks, exposed via context.forms. */
|
|
32
32
|
forms?: Record<string, CmssyFormDefinition>;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Async React Server Component (Next.js App Router / RSC). It runs each block's
|
|
36
|
+
* loader server-side before rendering, so it must be rendered in a server
|
|
37
|
+
* component tree (as `createCmssyPage` does) - not in a client component.
|
|
38
|
+
*/
|
|
39
|
+
declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, forms, }: CmssyServerPageProps): Promise<react_jsx_runtime.JSX.Element | null>;
|
|
35
40
|
|
|
36
41
|
interface CmssyServerLayoutProps {
|
|
37
42
|
groups: CmssyLayoutGroup[];
|
|
@@ -60,6 +65,8 @@ interface GraphqlRequestOptions {
|
|
|
60
65
|
}
|
|
61
66
|
declare function graphqlRequest<T>(config: CmssyClientConfig, query: string, variables: Record<string, unknown>, options?: GraphqlRequestOptions, label?: string): Promise<T>;
|
|
62
67
|
|
|
68
|
+
declare function resolveWorkspaceId(config: CmssyClientConfig, options?: GraphqlRequestOptions): Promise<string>;
|
|
69
|
+
|
|
63
70
|
interface QueryScopedOptions extends GraphqlRequestOptions {
|
|
64
71
|
workspaceId?: string;
|
|
65
72
|
}
|
|
@@ -101,4 +108,4 @@ interface UnknownBlockProps {
|
|
|
101
108
|
}
|
|
102
109
|
declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
|
|
103
110
|
|
|
104
|
-
export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteLocales, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, splitLocaleFromPath };
|
|
111
|
+
export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteLocales, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath };
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,13 @@ function buildBlockMap(blocks) {
|
|
|
33
33
|
for (const block of blocks) map[block.type] = block.component;
|
|
34
34
|
return map;
|
|
35
35
|
}
|
|
36
|
+
function buildLoaderMap(blocks) {
|
|
37
|
+
const map = /* @__PURE__ */ Object.create(null);
|
|
38
|
+
for (const block of blocks) {
|
|
39
|
+
if (block.loader) map[block.type] = block.loader;
|
|
40
|
+
}
|
|
41
|
+
return map;
|
|
42
|
+
}
|
|
36
43
|
function blocksToSchemas(blocks) {
|
|
37
44
|
const out = /* @__PURE__ */ Object.create(null);
|
|
38
45
|
for (const block of blocks) {
|
|
@@ -58,19 +65,6 @@ function blocksToMeta(blocks, defaults = {}) {
|
|
|
58
65
|
return out;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
|
-
// src/components/block-context.ts
|
|
62
|
-
function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
|
|
63
|
-
return {
|
|
64
|
-
locale: {
|
|
65
|
-
current: locale,
|
|
66
|
-
default: defaultLocale,
|
|
67
|
-
enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
|
|
68
|
-
},
|
|
69
|
-
isPreview: isPreview ?? false,
|
|
70
|
-
forms
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
68
|
// src/content/get-block-content.ts
|
|
75
69
|
function isPlainObject(value) {
|
|
76
70
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -94,6 +88,19 @@ function getBlockContentForLanguage(content, locale, defaultLocale = "en", avail
|
|
|
94
88
|
const chosen = localeMap[locale] ?? localeMap[defaultLocale] ?? localeMap[fallbackKey];
|
|
95
89
|
return { ...nonTranslatable, ...chosen };
|
|
96
90
|
}
|
|
91
|
+
|
|
92
|
+
// src/components/block-context.ts
|
|
93
|
+
function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
|
|
94
|
+
return {
|
|
95
|
+
locale: {
|
|
96
|
+
current: locale,
|
|
97
|
+
default: defaultLocale,
|
|
98
|
+
enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
|
|
99
|
+
},
|
|
100
|
+
isPreview: isPreview ?? false,
|
|
101
|
+
forms
|
|
102
|
+
};
|
|
103
|
+
}
|
|
97
104
|
var WARN_CAP = 256;
|
|
98
105
|
var warned = /* @__PURE__ */ new Set();
|
|
99
106
|
function UnknownBlock({ type }) {
|
|
@@ -104,12 +111,14 @@ function UnknownBlock({ type }) {
|
|
|
104
111
|
}
|
|
105
112
|
return /* @__PURE__ */ jsx("div", { "data-cmssy-unknown-block": type });
|
|
106
113
|
}
|
|
107
|
-
function renderResolvedBlock(block, map, locale, defaultLocale,
|
|
114
|
+
function renderResolvedBlock(block, map, locale, defaultLocale, options = {}) {
|
|
115
|
+
const { context, data, resolvedContent, enabledLocales } = options;
|
|
108
116
|
const Component = Object.hasOwn(map, block.type) ? map[block.type] : void 0;
|
|
109
|
-
const content = getBlockContentForLanguage(
|
|
117
|
+
const content = resolvedContent ?? getBlockContentForLanguage(
|
|
110
118
|
block.content,
|
|
111
119
|
locale,
|
|
112
|
-
defaultLocale
|
|
120
|
+
defaultLocale,
|
|
121
|
+
enabledLocales?.length ? enabledLocales : void 0
|
|
113
122
|
);
|
|
114
123
|
return /* @__PURE__ */ jsx(
|
|
115
124
|
"div",
|
|
@@ -117,12 +126,12 @@ function renderResolvedBlock(block, map, locale, defaultLocale, context) {
|
|
|
117
126
|
"data-block-id": block.id,
|
|
118
127
|
"data-block-type": block.type,
|
|
119
128
|
style: Component ? void 0 : { display: "none" },
|
|
120
|
-
children: Component ? createElement(Component, { content, context }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
|
|
129
|
+
children: Component ? createElement(Component, { content, context, data }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
|
|
121
130
|
},
|
|
122
131
|
block.id
|
|
123
132
|
);
|
|
124
133
|
}
|
|
125
|
-
function CmssyServerPage({
|
|
134
|
+
async function CmssyServerPage({
|
|
126
135
|
page,
|
|
127
136
|
blocks,
|
|
128
137
|
locale = "en",
|
|
@@ -132,6 +141,7 @@ function CmssyServerPage({
|
|
|
132
141
|
}) {
|
|
133
142
|
if (!page) return null;
|
|
134
143
|
const map = buildBlockMap(blocks);
|
|
144
|
+
const loaderMap = buildLoaderMap(blocks);
|
|
135
145
|
const context = buildBlockContext(
|
|
136
146
|
locale,
|
|
137
147
|
defaultLocale,
|
|
@@ -139,8 +149,38 @@ function CmssyServerPage({
|
|
|
139
149
|
false,
|
|
140
150
|
forms
|
|
141
151
|
);
|
|
152
|
+
const resolved = await Promise.all(
|
|
153
|
+
page.blocks.map(async (block) => {
|
|
154
|
+
const content = getBlockContentForLanguage(
|
|
155
|
+
block.content,
|
|
156
|
+
locale,
|
|
157
|
+
defaultLocale,
|
|
158
|
+
enabledLocales?.length ? enabledLocales : void 0
|
|
159
|
+
);
|
|
160
|
+
const loader = loaderMap[block.type];
|
|
161
|
+
let data;
|
|
162
|
+
if (loader) {
|
|
163
|
+
try {
|
|
164
|
+
data = await loader({ content, context });
|
|
165
|
+
} catch (err) {
|
|
166
|
+
if (typeof console !== "undefined") {
|
|
167
|
+
console.warn(
|
|
168
|
+
`[cmssy] loader for block "${block.type}" (${block.id}) failed`,
|
|
169
|
+
err
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { content, data };
|
|
175
|
+
})
|
|
176
|
+
);
|
|
142
177
|
return /* @__PURE__ */ jsx(Fragment, { children: page.blocks.map(
|
|
143
|
-
(block) => renderResolvedBlock(block, map, locale, defaultLocale,
|
|
178
|
+
(block, i) => renderResolvedBlock(block, map, locale, defaultLocale, {
|
|
179
|
+
context,
|
|
180
|
+
data: resolved[i]?.data,
|
|
181
|
+
resolvedContent: resolved[i]?.content,
|
|
182
|
+
enabledLocales
|
|
183
|
+
})
|
|
144
184
|
) });
|
|
145
185
|
}
|
|
146
186
|
function CmssyServerLayout({
|
|
@@ -157,7 +197,10 @@ function CmssyServerLayout({
|
|
|
157
197
|
const map = buildBlockMap(blocks);
|
|
158
198
|
const context = buildBlockContext(locale, defaultLocale, enabledLocales);
|
|
159
199
|
return /* @__PURE__ */ jsx(Fragment, { children: layoutBlocks.map(
|
|
160
|
-
(block) => renderResolvedBlock(block, map, locale, defaultLocale,
|
|
200
|
+
(block) => renderResolvedBlock(block, map, locale, defaultLocale, {
|
|
201
|
+
context,
|
|
202
|
+
enabledLocales
|
|
203
|
+
})
|
|
161
204
|
) });
|
|
162
205
|
}
|
|
163
206
|
|
|
@@ -611,4 +654,4 @@ function CmssyBlock({
|
|
|
611
654
|
);
|
|
612
655
|
}
|
|
613
656
|
|
|
614
|
-
export { CmssyBlock, CmssyServerLayout, CmssyServerPage, FORM_QUERY, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, PROTOCOL_VERSION, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockContext, buildBlockMap, collectFormIds, createCmssyClient, defineBlock, fetchLayouts, fetchPage, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, splitLocaleFromPath };
|
|
657
|
+
export { CmssyBlock, CmssyServerLayout, CmssyServerPage, FORM_QUERY, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, PROTOCOL_VERSION, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockContext, buildBlockMap, collectFormIds, createCmssyClient, defineBlock, fetchLayouts, fetchPage, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor, resolveForms, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath };
|
|
@@ -256,6 +256,11 @@ interface DragEndMessage {
|
|
|
256
256
|
type EditorToAppMessage = SelectMessage | PatchMessage | ParentReadyMessage | InsertMessage | ReorderMessage | RemoveMessage | DragOverMessage | DragEndMessage;
|
|
257
257
|
declare function isProtocolCompatible(version: number): boolean;
|
|
258
258
|
|
|
259
|
+
interface BlockLoaderArgs {
|
|
260
|
+
content: Record<string, unknown>;
|
|
261
|
+
context?: CmssyBlockContext;
|
|
262
|
+
}
|
|
263
|
+
type BlockLoader = (args: BlockLoaderArgs) => Promise<unknown> | unknown;
|
|
259
264
|
interface BlockDefinition {
|
|
260
265
|
type: string;
|
|
261
266
|
label?: string;
|
|
@@ -263,26 +268,43 @@ interface BlockDefinition {
|
|
|
263
268
|
icon?: string;
|
|
264
269
|
layoutPositions?: string[];
|
|
265
270
|
props: Record<string, FieldDefinition>;
|
|
271
|
+
/**
|
|
272
|
+
* Optional server-side data loader. Run by CmssyServerPage during SSR; its
|
|
273
|
+
* result is passed to the component as the `data` prop. Not run in the
|
|
274
|
+
* editor (the component receives `data: undefined` there).
|
|
275
|
+
*
|
|
276
|
+
* The result crosses the server→client boundary when the block component is a
|
|
277
|
+
* Client Component, so it must be RSC-serializable (plain objects, arrays and
|
|
278
|
+
* primitives - no functions, class instances, etc.).
|
|
279
|
+
*/
|
|
280
|
+
loader?: BlockLoader;
|
|
266
281
|
component: ComponentType<{
|
|
267
282
|
content: Record<string, unknown>;
|
|
268
283
|
context?: CmssyBlockContext;
|
|
284
|
+
data?: unknown;
|
|
269
285
|
}>;
|
|
270
286
|
}
|
|
271
|
-
declare function defineBlock<C extends Record<string, unknown
|
|
287
|
+
declare function defineBlock<C extends Record<string, unknown>, D = unknown>(def: {
|
|
272
288
|
type: string;
|
|
273
289
|
label?: string;
|
|
274
290
|
category?: string;
|
|
275
291
|
icon?: string;
|
|
276
292
|
layoutPositions?: string[];
|
|
277
293
|
props: Record<string, FieldDefinition>;
|
|
294
|
+
loader?: (args: {
|
|
295
|
+
content: C;
|
|
296
|
+
context?: CmssyBlockContext;
|
|
297
|
+
}) => Promise<D> | D;
|
|
278
298
|
component: ComponentType<{
|
|
279
299
|
content: C;
|
|
280
300
|
context?: CmssyBlockContext;
|
|
301
|
+
data?: D;
|
|
281
302
|
}>;
|
|
282
303
|
}): BlockDefinition;
|
|
283
304
|
type BlockMap = Record<string, ComponentType<{
|
|
284
305
|
content: Record<string, unknown>;
|
|
285
306
|
context?: CmssyBlockContext;
|
|
307
|
+
data?: unknown;
|
|
286
308
|
}>>;
|
|
287
309
|
declare function buildBlockMap(blocks: BlockDefinition[]): BlockMap;
|
|
288
310
|
declare function blocksToSchemas(blocks: BlockDefinition[]): Record<string, BlockSchema>;
|
|
@@ -256,6 +256,11 @@ interface DragEndMessage {
|
|
|
256
256
|
type EditorToAppMessage = SelectMessage | PatchMessage | ParentReadyMessage | InsertMessage | ReorderMessage | RemoveMessage | DragOverMessage | DragEndMessage;
|
|
257
257
|
declare function isProtocolCompatible(version: number): boolean;
|
|
258
258
|
|
|
259
|
+
interface BlockLoaderArgs {
|
|
260
|
+
content: Record<string, unknown>;
|
|
261
|
+
context?: CmssyBlockContext;
|
|
262
|
+
}
|
|
263
|
+
type BlockLoader = (args: BlockLoaderArgs) => Promise<unknown> | unknown;
|
|
259
264
|
interface BlockDefinition {
|
|
260
265
|
type: string;
|
|
261
266
|
label?: string;
|
|
@@ -263,26 +268,43 @@ interface BlockDefinition {
|
|
|
263
268
|
icon?: string;
|
|
264
269
|
layoutPositions?: string[];
|
|
265
270
|
props: Record<string, FieldDefinition>;
|
|
271
|
+
/**
|
|
272
|
+
* Optional server-side data loader. Run by CmssyServerPage during SSR; its
|
|
273
|
+
* result is passed to the component as the `data` prop. Not run in the
|
|
274
|
+
* editor (the component receives `data: undefined` there).
|
|
275
|
+
*
|
|
276
|
+
* The result crosses the server→client boundary when the block component is a
|
|
277
|
+
* Client Component, so it must be RSC-serializable (plain objects, arrays and
|
|
278
|
+
* primitives - no functions, class instances, etc.).
|
|
279
|
+
*/
|
|
280
|
+
loader?: BlockLoader;
|
|
266
281
|
component: ComponentType<{
|
|
267
282
|
content: Record<string, unknown>;
|
|
268
283
|
context?: CmssyBlockContext;
|
|
284
|
+
data?: unknown;
|
|
269
285
|
}>;
|
|
270
286
|
}
|
|
271
|
-
declare function defineBlock<C extends Record<string, unknown
|
|
287
|
+
declare function defineBlock<C extends Record<string, unknown>, D = unknown>(def: {
|
|
272
288
|
type: string;
|
|
273
289
|
label?: string;
|
|
274
290
|
category?: string;
|
|
275
291
|
icon?: string;
|
|
276
292
|
layoutPositions?: string[];
|
|
277
293
|
props: Record<string, FieldDefinition>;
|
|
294
|
+
loader?: (args: {
|
|
295
|
+
content: C;
|
|
296
|
+
context?: CmssyBlockContext;
|
|
297
|
+
}) => Promise<D> | D;
|
|
278
298
|
component: ComponentType<{
|
|
279
299
|
content: C;
|
|
280
300
|
context?: CmssyBlockContext;
|
|
301
|
+
data?: D;
|
|
281
302
|
}>;
|
|
282
303
|
}): BlockDefinition;
|
|
283
304
|
type BlockMap = Record<string, ComponentType<{
|
|
284
305
|
content: Record<string, unknown>;
|
|
285
306
|
context?: CmssyBlockContext;
|
|
307
|
+
data?: unknown;
|
|
286
308
|
}>>;
|
|
287
309
|
declare function buildBlockMap(blocks: BlockDefinition[]): BlockMap;
|
|
288
310
|
declare function blocksToSchemas(blocks: BlockDefinition[]): Record<string, BlockSchema>;
|