@cmssy/react 0.14.0 → 0.17.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/README.md CHANGED
@@ -39,7 +39,7 @@ the CMS at runtime.
39
39
  ```tsx
40
40
  import { fetchPage, CmssyServerPage } from "@cmssy/react";
41
41
 
42
- const page = await fetchPage({ workspaceSlug: "acme" }, pathSegments);
42
+ const page = await fetchPage({ org: "acme-org", workspaceSlug: "acme" }, pathSegments);
43
43
 
44
44
  return <CmssyServerPage page={page} blocks={blocks} locale="en" />;
45
45
  ```
@@ -56,7 +56,7 @@ the exported documents):
56
56
  ```ts
57
57
  import { createCmssyClient, MODEL_RECORDS_QUERY } from "@cmssy/react";
58
58
 
59
- const cmssy = createCmssyClient({ workspaceSlug: "acme" });
59
+ const cmssy = createCmssyClient({ org: "acme-org", workspaceSlug: "acme" });
60
60
 
61
61
  // raw query (you own scoping)
62
62
  await cmssy.query(MY_QUERY, vars);
package/dist/client.cjs CHANGED
@@ -74,6 +74,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
74
74
  blockId: data.blockId,
75
75
  content: data.content,
76
76
  protocolVersion: PROTOCOL_VERSION,
77
+ ...isObject(data.style) ? { style: data.style } : {},
78
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
77
79
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
78
80
  } : null;
79
81
  case "cmssy:parent-ready":
@@ -85,6 +87,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
85
87
  blockId: data.blockId,
86
88
  blockType: data.blockType,
87
89
  content: data.content,
90
+ ...isObject(data.style) ? { style: data.style } : {},
91
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
88
92
  index: data.index
89
93
  } : null;
90
94
  case "cmssy:reorder":
@@ -148,6 +152,8 @@ function collectLayoutBlocks(rects, pageIds) {
148
152
  }
149
153
  function useEditBridge(page, config) {
150
154
  const [patches, setPatches] = react.useState({});
155
+ const [patchesStyle, setPatchesStyle] = react.useState({});
156
+ const [patchesAdvanced, setPatchesAdvanced] = react.useState({});
151
157
  const [selected, setSelected] = react.useState(null);
152
158
  const [inserted, setInserted] = react.useState([]);
153
159
  const [order, setOrder] = react.useState(null);
@@ -157,6 +163,8 @@ function useEditBridge(page, config) {
157
163
  const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
158
164
  react.useEffect(() => {
159
165
  setPatches({});
166
+ setPatchesStyle({});
167
+ setPatchesAdvanced({});
160
168
  setSelected(null);
161
169
  setInserted([]);
162
170
  setOrder(null);
@@ -209,6 +217,21 @@ function useEditBridge(page, config) {
209
217
  ...prev,
210
218
  [message.blockId]: { ...prev[message.blockId], ...message.content }
211
219
  }));
220
+ if (message.style) {
221
+ setPatchesStyle((prev) => ({
222
+ ...prev,
223
+ [message.blockId]: { ...prev[message.blockId], ...message.style }
224
+ }));
225
+ }
226
+ if (message.advanced) {
227
+ setPatchesAdvanced((prev) => ({
228
+ ...prev,
229
+ [message.blockId]: {
230
+ ...prev[message.blockId],
231
+ ...message.advanced
232
+ }
233
+ }));
234
+ }
212
235
  } else if (message.type === "cmssy:select") {
213
236
  setSelected(message.blockId);
214
237
  selectedIdRef.current = message.blockId;
@@ -219,6 +242,8 @@ function useEditBridge(page, config) {
219
242
  blockId: message.blockId,
220
243
  blockType: message.blockType,
221
244
  content: message.content,
245
+ style: message.style,
246
+ advanced: message.advanced,
222
247
  index: message.index
223
248
  });
224
249
  return next;
@@ -295,7 +320,15 @@ function useEditBridge(page, config) {
295
320
  window.removeEventListener("resize", emitSelectedBounds);
296
321
  };
297
322
  }, [config.editorOrigin, pageId, blocksKey]);
298
- return { patches, selected, inserted, order, removed };
323
+ return {
324
+ patches,
325
+ patchesStyle,
326
+ patchesAdvanced,
327
+ selected,
328
+ inserted,
329
+ order,
330
+ removed
331
+ };
299
332
  }
300
333
  var MOVE_MIME = "application/x-cmssy-move";
301
334
  function visible(el) {
@@ -504,6 +537,8 @@ function CmssyBlock({
504
537
  defaultLocale,
505
538
  blockMap,
506
539
  patchedContent,
540
+ patchedStyle,
541
+ patchedAdvanced,
507
542
  editable,
508
543
  layoutPosition,
509
544
  context
@@ -511,6 +546,8 @@ function CmssyBlock({
511
546
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
512
547
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
513
548
  const content = patchedContent ? { ...base, ...patchedContent } : base;
549
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
550
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
514
551
  return /* @__PURE__ */ jsxRuntime.jsx(
515
552
  "div",
516
553
  {
@@ -521,8 +558,8 @@ function CmssyBlock({
521
558
  style: Component ? void 0 : { display: "none" },
522
559
  children: Component ? react.createElement(Component, {
523
560
  content,
524
- style: asBucket(block.style),
525
- advanced: asBucket(block.advanced),
561
+ style,
562
+ advanced,
526
563
  context
527
564
  }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
528
565
  }
@@ -581,10 +618,7 @@ function EditableBlocks({
581
618
  }),
582
619
  [edit, blocks, category]
583
620
  );
584
- const { patches, inserted, order, removed } = useEditBridge(
585
- page,
586
- bridgeConfig
587
- );
621
+ const { patches, patchesStyle, patchesAdvanced, inserted, order, removed } = useEditBridge(page, bridgeConfig);
588
622
  const { dropY } = useDragAgent(bridgeConfig);
589
623
  const renderBlocks = react.useMemo(() => {
590
624
  const removedSet = new Set(removed);
@@ -595,7 +629,9 @@ function EditableBlocks({
595
629
  merged.splice(at, 0, {
596
630
  id: ins.blockId,
597
631
  type: ins.blockType,
598
- content: ins.content
632
+ content: ins.content,
633
+ style: ins.style,
634
+ advanced: ins.advanced
599
635
  });
600
636
  }
601
637
  if (order) {
@@ -615,6 +651,8 @@ function EditableBlocks({
615
651
  locale,
616
652
  defaultLocale,
617
653
  patchedContent: patches[block.id],
654
+ patchedStyle: patchesStyle[block.id],
655
+ patchedAdvanced: patchesAdvanced[block.id],
618
656
  blockMap,
619
657
  editable: true,
620
658
  context
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, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-D5duQ6QF.cjs';
3
- export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-D5duQ6QF.cjs';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-CxUeiT52.cjs';
3
+ export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-CxUeiT52.cjs';
4
4
  import { ReactNode } from 'react';
5
5
  import '@cmssy/types';
6
6
 
@@ -14,10 +14,14 @@ interface InsertedBlock {
14
14
  blockId: string;
15
15
  blockType: string;
16
16
  content: Record<string, unknown>;
17
+ style?: Record<string, unknown>;
18
+ advanced?: Record<string, unknown>;
17
19
  index: number;
18
20
  }
19
21
  interface EditBridgeState {
20
22
  patches: PatchMap;
23
+ patchesStyle: PatchMap;
24
+ patchesAdvanced: PatchMap;
21
25
  selected: string | null;
22
26
  inserted: InsertedBlock[];
23
27
  order: string[] | null;
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, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-D5duQ6QF.js';
3
- export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-D5duQ6QF.js';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-CxUeiT52.js';
3
+ export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-CxUeiT52.js';
4
4
  import { ReactNode } from 'react';
5
5
  import '@cmssy/types';
6
6
 
@@ -14,10 +14,14 @@ interface InsertedBlock {
14
14
  blockId: string;
15
15
  blockType: string;
16
16
  content: Record<string, unknown>;
17
+ style?: Record<string, unknown>;
18
+ advanced?: Record<string, unknown>;
17
19
  index: number;
18
20
  }
19
21
  interface EditBridgeState {
20
22
  patches: PatchMap;
23
+ patchesStyle: PatchMap;
24
+ patchesAdvanced: PatchMap;
21
25
  selected: string | null;
22
26
  inserted: InsertedBlock[];
23
27
  order: string[] | null;
package/dist/client.js CHANGED
@@ -72,6 +72,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
72
72
  blockId: data.blockId,
73
73
  content: data.content,
74
74
  protocolVersion: PROTOCOL_VERSION,
75
+ ...isObject(data.style) ? { style: data.style } : {},
76
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
75
77
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
76
78
  } : null;
77
79
  case "cmssy:parent-ready":
@@ -83,6 +85,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
83
85
  blockId: data.blockId,
84
86
  blockType: data.blockType,
85
87
  content: data.content,
88
+ ...isObject(data.style) ? { style: data.style } : {},
89
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
86
90
  index: data.index
87
91
  } : null;
88
92
  case "cmssy:reorder":
@@ -146,6 +150,8 @@ function collectLayoutBlocks(rects, pageIds) {
146
150
  }
147
151
  function useEditBridge(page, config) {
148
152
  const [patches, setPatches] = useState({});
153
+ const [patchesStyle, setPatchesStyle] = useState({});
154
+ const [patchesAdvanced, setPatchesAdvanced] = useState({});
149
155
  const [selected, setSelected] = useState(null);
150
156
  const [inserted, setInserted] = useState([]);
151
157
  const [order, setOrder] = useState(null);
@@ -155,6 +161,8 @@ function useEditBridge(page, config) {
155
161
  const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
156
162
  useEffect(() => {
157
163
  setPatches({});
164
+ setPatchesStyle({});
165
+ setPatchesAdvanced({});
158
166
  setSelected(null);
159
167
  setInserted([]);
160
168
  setOrder(null);
@@ -207,6 +215,21 @@ function useEditBridge(page, config) {
207
215
  ...prev,
208
216
  [message.blockId]: { ...prev[message.blockId], ...message.content }
209
217
  }));
218
+ if (message.style) {
219
+ setPatchesStyle((prev) => ({
220
+ ...prev,
221
+ [message.blockId]: { ...prev[message.blockId], ...message.style }
222
+ }));
223
+ }
224
+ if (message.advanced) {
225
+ setPatchesAdvanced((prev) => ({
226
+ ...prev,
227
+ [message.blockId]: {
228
+ ...prev[message.blockId],
229
+ ...message.advanced
230
+ }
231
+ }));
232
+ }
210
233
  } else if (message.type === "cmssy:select") {
211
234
  setSelected(message.blockId);
212
235
  selectedIdRef.current = message.blockId;
@@ -217,6 +240,8 @@ function useEditBridge(page, config) {
217
240
  blockId: message.blockId,
218
241
  blockType: message.blockType,
219
242
  content: message.content,
243
+ style: message.style,
244
+ advanced: message.advanced,
220
245
  index: message.index
221
246
  });
222
247
  return next;
@@ -293,7 +318,15 @@ function useEditBridge(page, config) {
293
318
  window.removeEventListener("resize", emitSelectedBounds);
294
319
  };
295
320
  }, [config.editorOrigin, pageId, blocksKey]);
296
- return { patches, selected, inserted, order, removed };
321
+ return {
322
+ patches,
323
+ patchesStyle,
324
+ patchesAdvanced,
325
+ selected,
326
+ inserted,
327
+ order,
328
+ removed
329
+ };
297
330
  }
298
331
  var MOVE_MIME = "application/x-cmssy-move";
299
332
  function visible(el) {
@@ -502,6 +535,8 @@ function CmssyBlock({
502
535
  defaultLocale,
503
536
  blockMap,
504
537
  patchedContent,
538
+ patchedStyle,
539
+ patchedAdvanced,
505
540
  editable,
506
541
  layoutPosition,
507
542
  context
@@ -509,6 +544,8 @@ function CmssyBlock({
509
544
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
510
545
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
511
546
  const content = patchedContent ? { ...base, ...patchedContent } : base;
547
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
548
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
512
549
  return /* @__PURE__ */ jsx(
513
550
  "div",
514
551
  {
@@ -519,8 +556,8 @@ function CmssyBlock({
519
556
  style: Component ? void 0 : { display: "none" },
520
557
  children: Component ? createElement(Component, {
521
558
  content,
522
- style: asBucket(block.style),
523
- advanced: asBucket(block.advanced),
559
+ style,
560
+ advanced,
524
561
  context
525
562
  }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
526
563
  }
@@ -579,10 +616,7 @@ function EditableBlocks({
579
616
  }),
580
617
  [edit, blocks, category]
581
618
  );
582
- const { patches, inserted, order, removed } = useEditBridge(
583
- page,
584
- bridgeConfig
585
- );
619
+ const { patches, patchesStyle, patchesAdvanced, inserted, order, removed } = useEditBridge(page, bridgeConfig);
586
620
  const { dropY } = useDragAgent(bridgeConfig);
587
621
  const renderBlocks = useMemo(() => {
588
622
  const removedSet = new Set(removed);
@@ -593,7 +627,9 @@ function EditableBlocks({
593
627
  merged.splice(at, 0, {
594
628
  id: ins.blockId,
595
629
  type: ins.blockType,
596
- content: ins.content
630
+ content: ins.content,
631
+ style: ins.style,
632
+ advanced: ins.advanced
597
633
  });
598
634
  }
599
635
  if (order) {
@@ -613,6 +649,8 @@ function EditableBlocks({
613
649
  locale,
614
650
  defaultLocale,
615
651
  patchedContent: patches[block.id],
652
+ patchedStyle: patchesStyle[block.id],
653
+ patchedAdvanced: patchesAdvanced[block.id],
616
654
  blockMap,
617
655
  editable: true,
618
656
  context
@@ -8,9 +8,22 @@ import { FieldConditionGroup, FieldType } from '@cmssy/types';
8
8
  */
9
9
  declare const DEFAULT_CMSSY_API_URL = "https://api.cmssy.io/graphql";
10
10
  declare function resolveApiUrl(apiUrl: string | undefined): string;
11
+ /**
12
+ * Public delivery endpoint for a workspace: the org-scoped path
13
+ * `{base}/public/{orgSlug}/{workspaceSlug}/graphql`. `apiUrl` is the GraphQL
14
+ * base (its trailing `/graphql` is stripped); the org path is what tells the
15
+ * backend which workspace to serve, so slugs only need to be unique per org.
16
+ */
17
+ declare function resolvePublicUrl(config: CmssyClientConfig): string;
11
18
  interface CmssyClientConfig {
12
- /** Full GraphQL delivery endpoint. Defaults to {@link DEFAULT_CMSSY_API_URL}. */
19
+ /**
20
+ * Full GraphQL endpoint (used as-is for authenticated requests). Defaults to
21
+ * {@link DEFAULT_CMSSY_API_URL}. Public reads strip its trailing `/graphql`
22
+ * and append the org-scoped path (see {@link resolvePublicUrl}).
23
+ */
13
24
  apiUrl?: string;
25
+ /** Organization slug - part of the org-scoped delivery path. */
26
+ org: string;
14
27
  workspaceSlug: string;
15
28
  }
16
29
  interface FetchLikeResponse {
@@ -94,7 +107,7 @@ interface CmssySiteConfig {
94
107
  previewUrl: string | null;
95
108
  branding: CmssyBranding | null;
96
109
  }
97
- declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n publicSiteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n faviconUrl\n ogImageUrl\n }\n }\n}";
110
+ declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n public {\n siteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n faviconUrl\n ogImageUrl\n }\n }\n }\n}";
98
111
  interface CmssyModelDefinition {
99
112
  id: string;
100
113
  name: string;
@@ -275,6 +288,8 @@ interface PatchMessage {
275
288
  protocolVersion: number;
276
289
  blockId: string;
277
290
  content: Record<string, unknown>;
291
+ style?: Record<string, unknown>;
292
+ advanced?: Record<string, unknown>;
278
293
  layoutPosition?: string;
279
294
  }
280
295
  interface ParentReadyMessage {
@@ -287,6 +302,8 @@ interface InsertMessage {
287
302
  blockId: string;
288
303
  blockType: string;
289
304
  content: Record<string, unknown>;
305
+ style?: Record<string, unknown>;
306
+ advanced?: Record<string, unknown>;
290
307
  index: number;
291
308
  }
292
309
  interface ReorderMessage {
@@ -475,4 +492,4 @@ interface CmssyOrder {
475
492
  createdAt?: string;
476
493
  }
477
494
 
478
- export { SUBMIT_FORM_MUTATION as $, type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type CmssyFormField as D, type EditorToAppMessage as E, type FieldDefinition as F, type CmssyFormSettings as G, type CmssyFormSubmitResponse as H, type CmssyLocalizedValue as I, type CmssyModelDefinition as J, type CmssyModelRecord as K, type CmssyPageMeta as L, type CmssyPageSummary as M, type CmssyRecordList as N, DEFAULT_CMSSY_API_URL as O, FORM_QUERY as P, type FetchLikeResponse as Q, type RawBlock as R, type FetchPageOptions as S, MODEL_DEFINITIONS_QUERY as T, MODEL_RECORDS_QUERY as U, PROTOCOL_VERSION as V, type ParentReadyMessage as W, type PatchMessage as X, type RawLayoutBlock as Y, type ReadyMessage as Z, SITE_CONFIG_QUERY as _, type BlockMeta as a, type SelectMessage as a0, type SubmitFormInput as a1, blocksToMeta as a2, blocksToSchemas as a3, buildBlockContext as a4, buildBlockMap as a5, defineBlock as a6, fetchLayouts as a7, fetchPage as a8, fetchPageById as a9, fetchPageMeta as aa, fetchPages as ab, isProtocolCompatible as ac, normalizeSlug as ad, resolveApiUrl as ae, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type CmssyLocaleContext as e, type CmssyCart as f, type CmssyOrder as g, type CmssyProduct as h, type CmssyCartDiscount as i, type CmssyCartItem as j, type CmssyCartItemSnapshot as k, type CmssyOrderItem as l, type CmssyProductVariant as m, type CmssyBlockAuthContext as n, type CmssyBlockWorkspace as o, type FetchLike as p, type CmssyClientConfig as q, type CmssySiteConfig as r, type BlockMap as s, type CmssyBlockContext as t, type BlockRect as u, type BoundsMessage as v, type BuildBlockContextExtra as w, type ClickMessage as x, type CmssyBlockMember as y, type CmssyBranding as z };
495
+ export { SUBMIT_FORM_MUTATION as $, type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type CmssyFormField as D, type EditorToAppMessage as E, type FieldDefinition as F, type CmssyFormSettings as G, type CmssyFormSubmitResponse as H, type CmssyLocalizedValue as I, type CmssyModelDefinition as J, type CmssyModelRecord as K, type CmssyPageMeta as L, type CmssyPageSummary as M, type CmssyRecordList as N, DEFAULT_CMSSY_API_URL as O, FORM_QUERY as P, type FetchLikeResponse as Q, type RawBlock as R, type FetchPageOptions as S, MODEL_DEFINITIONS_QUERY as T, MODEL_RECORDS_QUERY as U, PROTOCOL_VERSION as V, type ParentReadyMessage as W, type PatchMessage as X, type RawLayoutBlock as Y, type ReadyMessage as Z, SITE_CONFIG_QUERY as _, type BlockMeta as a, type SelectMessage as a0, type SubmitFormInput as a1, blocksToMeta as a2, blocksToSchemas as a3, buildBlockContext as a4, buildBlockMap as a5, defineBlock as a6, fetchLayouts as a7, fetchPage as a8, fetchPageById as a9, fetchPageMeta as aa, fetchPages as ab, isProtocolCompatible as ac, normalizeSlug as ad, resolveApiUrl as ae, resolvePublicUrl as af, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type CmssyLocaleContext as e, type CmssyCart as f, type CmssyOrder as g, type CmssyProduct as h, type CmssyCartDiscount as i, type CmssyCartItem as j, type CmssyCartItemSnapshot as k, type CmssyOrderItem as l, type CmssyProductVariant as m, type CmssyBlockAuthContext as n, type CmssyBlockWorkspace as o, type FetchLike as p, type CmssyClientConfig as q, type CmssySiteConfig as r, type BlockMap as s, type CmssyBlockContext as t, type BlockRect as u, type BoundsMessage as v, type BuildBlockContextExtra as w, type ClickMessage as x, type CmssyBlockMember as y, type CmssyBranding as z };
@@ -8,9 +8,22 @@ import { FieldConditionGroup, FieldType } from '@cmssy/types';
8
8
  */
9
9
  declare const DEFAULT_CMSSY_API_URL = "https://api.cmssy.io/graphql";
10
10
  declare function resolveApiUrl(apiUrl: string | undefined): string;
11
+ /**
12
+ * Public delivery endpoint for a workspace: the org-scoped path
13
+ * `{base}/public/{orgSlug}/{workspaceSlug}/graphql`. `apiUrl` is the GraphQL
14
+ * base (its trailing `/graphql` is stripped); the org path is what tells the
15
+ * backend which workspace to serve, so slugs only need to be unique per org.
16
+ */
17
+ declare function resolvePublicUrl(config: CmssyClientConfig): string;
11
18
  interface CmssyClientConfig {
12
- /** Full GraphQL delivery endpoint. Defaults to {@link DEFAULT_CMSSY_API_URL}. */
19
+ /**
20
+ * Full GraphQL endpoint (used as-is for authenticated requests). Defaults to
21
+ * {@link DEFAULT_CMSSY_API_URL}. Public reads strip its trailing `/graphql`
22
+ * and append the org-scoped path (see {@link resolvePublicUrl}).
23
+ */
13
24
  apiUrl?: string;
25
+ /** Organization slug - part of the org-scoped delivery path. */
26
+ org: string;
14
27
  workspaceSlug: string;
15
28
  }
16
29
  interface FetchLikeResponse {
@@ -94,7 +107,7 @@ interface CmssySiteConfig {
94
107
  previewUrl: string | null;
95
108
  branding: CmssyBranding | null;
96
109
  }
97
- declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n publicSiteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n faviconUrl\n ogImageUrl\n }\n }\n}";
110
+ declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n public {\n siteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n faviconUrl\n ogImageUrl\n }\n }\n }\n}";
98
111
  interface CmssyModelDefinition {
99
112
  id: string;
100
113
  name: string;
@@ -275,6 +288,8 @@ interface PatchMessage {
275
288
  protocolVersion: number;
276
289
  blockId: string;
277
290
  content: Record<string, unknown>;
291
+ style?: Record<string, unknown>;
292
+ advanced?: Record<string, unknown>;
278
293
  layoutPosition?: string;
279
294
  }
280
295
  interface ParentReadyMessage {
@@ -287,6 +302,8 @@ interface InsertMessage {
287
302
  blockId: string;
288
303
  blockType: string;
289
304
  content: Record<string, unknown>;
305
+ style?: Record<string, unknown>;
306
+ advanced?: Record<string, unknown>;
290
307
  index: number;
291
308
  }
292
309
  interface ReorderMessage {
@@ -475,4 +492,4 @@ interface CmssyOrder {
475
492
  createdAt?: string;
476
493
  }
477
494
 
478
- export { SUBMIT_FORM_MUTATION as $, type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type CmssyFormField as D, type EditorToAppMessage as E, type FieldDefinition as F, type CmssyFormSettings as G, type CmssyFormSubmitResponse as H, type CmssyLocalizedValue as I, type CmssyModelDefinition as J, type CmssyModelRecord as K, type CmssyPageMeta as L, type CmssyPageSummary as M, type CmssyRecordList as N, DEFAULT_CMSSY_API_URL as O, FORM_QUERY as P, type FetchLikeResponse as Q, type RawBlock as R, type FetchPageOptions as S, MODEL_DEFINITIONS_QUERY as T, MODEL_RECORDS_QUERY as U, PROTOCOL_VERSION as V, type ParentReadyMessage as W, type PatchMessage as X, type RawLayoutBlock as Y, type ReadyMessage as Z, SITE_CONFIG_QUERY as _, type BlockMeta as a, type SelectMessage as a0, type SubmitFormInput as a1, blocksToMeta as a2, blocksToSchemas as a3, buildBlockContext as a4, buildBlockMap as a5, defineBlock as a6, fetchLayouts as a7, fetchPage as a8, fetchPageById as a9, fetchPageMeta as aa, fetchPages as ab, isProtocolCompatible as ac, normalizeSlug as ad, resolveApiUrl as ae, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type CmssyLocaleContext as e, type CmssyCart as f, type CmssyOrder as g, type CmssyProduct as h, type CmssyCartDiscount as i, type CmssyCartItem as j, type CmssyCartItemSnapshot as k, type CmssyOrderItem as l, type CmssyProductVariant as m, type CmssyBlockAuthContext as n, type CmssyBlockWorkspace as o, type FetchLike as p, type CmssyClientConfig as q, type CmssySiteConfig as r, type BlockMap as s, type CmssyBlockContext as t, type BlockRect as u, type BoundsMessage as v, type BuildBlockContextExtra as w, type ClickMessage as x, type CmssyBlockMember as y, type CmssyBranding as z };
495
+ export { SUBMIT_FORM_MUTATION as $, type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type CmssyFormField as D, type EditorToAppMessage as E, type FieldDefinition as F, type CmssyFormSettings as G, type CmssyFormSubmitResponse as H, type CmssyLocalizedValue as I, type CmssyModelDefinition as J, type CmssyModelRecord as K, type CmssyPageMeta as L, type CmssyPageSummary as M, type CmssyRecordList as N, DEFAULT_CMSSY_API_URL as O, FORM_QUERY as P, type FetchLikeResponse as Q, type RawBlock as R, type FetchPageOptions as S, MODEL_DEFINITIONS_QUERY as T, MODEL_RECORDS_QUERY as U, PROTOCOL_VERSION as V, type ParentReadyMessage as W, type PatchMessage as X, type RawLayoutBlock as Y, type ReadyMessage as Z, SITE_CONFIG_QUERY as _, type BlockMeta as a, type SelectMessage as a0, type SubmitFormInput as a1, blocksToMeta as a2, blocksToSchemas as a3, buildBlockContext as a4, buildBlockMap as a5, defineBlock as a6, fetchLayouts as a7, fetchPage as a8, fetchPageById as a9, fetchPageMeta as aa, fetchPages as ab, isProtocolCompatible as ac, normalizeSlug as ad, resolveApiUrl as ae, resolvePublicUrl as af, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type CmssyLocaleContext as e, type CmssyCart as f, type CmssyOrder as g, type CmssyProduct as h, type CmssyCartDiscount as i, type CmssyCartItem as j, type CmssyCartItemSnapshot as k, type CmssyOrderItem as l, type CmssyProductVariant as m, type CmssyBlockAuthContext as n, type CmssyBlockWorkspace as o, type FetchLike as p, type CmssyClientConfig as q, type CmssySiteConfig as r, type BlockMap as s, type CmssyBlockContext as t, type BlockRect as u, type BoundsMessage as v, type BuildBlockContextExtra as w, type ClickMessage as x, type CmssyBlockMember as y, type CmssyBranding as z };
package/dist/index.cjs CHANGED
@@ -269,6 +269,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
269
269
  blockId: data.blockId,
270
270
  content: data.content,
271
271
  protocolVersion: PROTOCOL_VERSION,
272
+ ...isObject(data.style) ? { style: data.style } : {},
273
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
272
274
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
273
275
  } : null;
274
276
  case "cmssy:parent-ready":
@@ -280,6 +282,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
280
282
  blockId: data.blockId,
281
283
  blockType: data.blockType,
282
284
  content: data.content,
285
+ ...isObject(data.style) ? { style: data.style } : {},
286
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
283
287
  index: data.index
284
288
  } : null;
285
289
  case "cmssy:reorder":
@@ -316,6 +320,10 @@ function resolveApiUrl(apiUrl) {
316
320
  const fromEnv = env?.CMSSY_API_URL?.trim() ?? "";
317
321
  return fromEnv.length > 0 ? fromEnv : DEFAULT_CMSSY_API_URL;
318
322
  }
323
+ function resolvePublicUrl(config) {
324
+ const base = resolveApiUrl(config.apiUrl).replace(/\/graphql\/?$/, "");
325
+ return `${base}/public/${config.org}/${config.workspaceSlug}/graphql`;
326
+ }
319
327
  var PUBLIC_PAGE_QUERY = `query PublicPage($workspaceSlug: String!, $slug: String!, $previewSecret: String) {
320
328
  public {
321
329
  page {
@@ -412,7 +420,7 @@ async function fetchPage(config, path, options = {}) {
412
420
  headers["x-workspace-id"] = options.workspaceId;
413
421
  }
414
422
  }
415
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
423
+ const response = await doFetch(resolvePublicUrl(config), {
416
424
  method: "POST",
417
425
  headers,
418
426
  body: JSON.stringify({
@@ -461,7 +469,7 @@ async function fetchPageById(config, pageId, options = {}) {
461
469
  "cmssy: no fetch implementation available - pass options.fetch"
462
470
  );
463
471
  }
464
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
472
+ const response = await doFetch(resolvePublicUrl(config), {
465
473
  method: "POST",
466
474
  headers: { "content-type": "application/json" },
467
475
  body: JSON.stringify({
@@ -505,7 +513,7 @@ async function fetchPages(config, options = {}) {
505
513
  "cmssy: no fetch implementation available - pass options.fetch"
506
514
  );
507
515
  }
508
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
516
+ const response = await doFetch(resolvePublicUrl(config), {
509
517
  method: "POST",
510
518
  headers: { "content-type": "application/json" },
511
519
  body: JSON.stringify({
@@ -537,7 +545,7 @@ async function fetchPageMeta(config, path, options = {}) {
537
545
  "cmssy: no fetch implementation available - pass options.fetch"
538
546
  );
539
547
  }
540
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
548
+ const response = await doFetch(resolvePublicUrl(config), {
541
549
  method: "POST",
542
550
  headers: { "content-type": "application/json" },
543
551
  body: JSON.stringify({
@@ -571,7 +579,7 @@ async function fetchLayouts(config, path, options = {}) {
571
579
  }
572
580
  const trimmedSecret = options.previewSecret?.trim();
573
581
  const previewSecret = trimmedSecret ? trimmedSecret : null;
574
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
582
+ const response = await doFetch(resolvePublicUrl(config), {
575
583
  method: "POST",
576
584
  headers: { "content-type": "application/json" },
577
585
  body: JSON.stringify({
@@ -608,7 +616,8 @@ async function graphqlRequest(config, query, variables, options = {}, label = "r
608
616
  "cmssy: no fetch implementation available - pass options.fetch"
609
617
  );
610
618
  }
611
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
619
+ const url = options.public ? resolvePublicUrl(config) : resolveApiUrl(config.apiUrl);
620
+ const response = await doFetch(url, {
612
621
  method: "POST",
613
622
  headers: { "content-type": "application/json", ...options.headers },
614
623
  body: JSON.stringify({ query, variables }),
@@ -641,20 +650,22 @@ async function graphqlRequest(config, query, variables, options = {}, label = "r
641
650
 
642
651
  // src/data/queries.ts
643
652
  var SITE_CONFIG_QUERY = `query PublicSiteConfig($workspaceSlug: String!) {
644
- publicSiteConfig(workspaceSlug: $workspaceSlug) {
645
- id
646
- workspaceId
647
- siteName
648
- defaultLanguage
649
- enabledLanguages
650
- enabledFeatures
651
- notFoundPageId
652
- previewUrl
653
- branding {
654
- brandName
655
- logoUrl
656
- faviconUrl
657
- ogImageUrl
653
+ public {
654
+ siteConfig(workspaceSlug: $workspaceSlug) {
655
+ id
656
+ workspaceId
657
+ siteName
658
+ defaultLanguage
659
+ enabledLanguages
660
+ enabledFeatures
661
+ notFoundPageId
662
+ previewUrl
663
+ branding {
664
+ brandName
665
+ logoUrl
666
+ faviconUrl
667
+ ogImageUrl
668
+ }
658
669
  }
659
670
  }
660
671
  }`;
@@ -700,10 +711,10 @@ async function fetchSiteConfig(config, options = {}) {
700
711
  config,
701
712
  SITE_CONFIG_QUERY,
702
713
  { workspaceSlug: config.workspaceSlug },
703
- options,
714
+ { ...options, public: true },
704
715
  "site config query"
705
716
  );
706
- return data.publicSiteConfig ?? null;
717
+ return data.public?.siteConfig ?? null;
707
718
  }
708
719
  async function resolveWorkspaceId(config, options = {}) {
709
720
  const siteConfig = await fetchSiteConfig(config, options);
@@ -806,7 +817,7 @@ var TTL_MS = 6e4;
806
817
  var MAX_ENTRIES = 64;
807
818
  var cache = /* @__PURE__ */ new Map();
808
819
  async function resolveSiteLocales(config, options) {
809
- const key = `${resolveApiUrl(config.apiUrl)}::${config.workspaceSlug}`;
820
+ const key = `${resolveApiUrl(config.apiUrl)}::${config.org}::${config.workspaceSlug}`;
810
821
  const cached = cache.get(key);
811
822
  if (cached && cached.expires > Date.now()) return cached.value;
812
823
  cache.delete(key);
@@ -816,10 +827,10 @@ async function resolveSiteLocales(config, options) {
816
827
  config,
817
828
  SITE_CONFIG_QUERY,
818
829
  { workspaceSlug: config.workspaceSlug },
819
- options,
830
+ { ...options, public: true },
820
831
  "site config"
821
832
  );
822
- const siteConfig = data.publicSiteConfig;
833
+ const siteConfig = data.public?.siteConfig ?? null;
823
834
  const defaultLocale = siteConfig?.defaultLanguage || "en";
824
835
  const enabled = siteConfig?.enabledLanguages ?? [];
825
836
  value = {
@@ -892,6 +903,8 @@ function CmssyBlock({
892
903
  defaultLocale,
893
904
  blockMap,
894
905
  patchedContent,
906
+ patchedStyle,
907
+ patchedAdvanced,
895
908
  editable,
896
909
  layoutPosition,
897
910
  context
@@ -899,6 +912,8 @@ function CmssyBlock({
899
912
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
900
913
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
901
914
  const content = patchedContent ? { ...base, ...patchedContent } : base;
915
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
916
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
902
917
  return /* @__PURE__ */ jsxRuntime.jsx(
903
918
  "div",
904
919
  {
@@ -909,8 +924,8 @@ function CmssyBlock({
909
924
  style: Component ? void 0 : { display: "none" },
910
925
  children: Component ? react.createElement(Component, {
911
926
  content,
912
- style: asBucket(block.style),
913
- advanced: asBucket(block.advanced),
927
+ style,
928
+ advanced,
914
929
  context
915
930
  }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
916
931
  }
@@ -958,6 +973,7 @@ exports.parseEditorMessage = parseEditorMessage;
958
973
  exports.postToEditor = postToEditor;
959
974
  exports.resolveApiUrl = resolveApiUrl;
960
975
  exports.resolveForms = resolveForms;
976
+ exports.resolvePublicUrl = resolvePublicUrl;
961
977
  exports.resolveSiteLocales = resolveSiteLocales;
962
978
  exports.resolveWorkspaceId = resolveWorkspaceId;
963
979
  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, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-D5duQ6QF.cjs';
2
- export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl } from './commerce-queries-D5duQ6QF.cjs';
1
+ import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-CxUeiT52.cjs';
2
+ export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-CxUeiT52.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, FieldType, evaluateFieldConditionGroup } from '@cmssy/types';
5
5
  import 'react';
@@ -76,6 +76,12 @@ interface GraphqlRequestOptions {
76
76
  fetch?: FetchLike;
77
77
  signal?: AbortSignal;
78
78
  headers?: Record<string, string>;
79
+ /**
80
+ * Route through the org-scoped public delivery path instead of the base
81
+ * `/graphql` endpoint. Set for unauthenticated public queries so the backend
82
+ * resolves the workspace from the URL rather than a global slug lookup.
83
+ */
84
+ public?: boolean;
79
85
  }
80
86
  declare function graphqlRequest<T>(config: CmssyClientConfig, query: string, variables: Record<string, unknown>, options?: GraphqlRequestOptions, label?: string): Promise<T>;
81
87
 
@@ -129,11 +135,13 @@ interface CmssyBlockProps {
129
135
  defaultLocale: string;
130
136
  blockMap: BlockMap;
131
137
  patchedContent?: Record<string, unknown>;
138
+ patchedStyle?: Record<string, unknown>;
139
+ patchedAdvanced?: Record<string, unknown>;
132
140
  editable?: boolean;
133
141
  layoutPosition?: string;
134
142
  context?: CmssyBlockContext;
135
143
  }
136
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
144
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
137
145
 
138
146
  interface UnknownBlockProps {
139
147
  type: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-D5duQ6QF.js';
2
- export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl } from './commerce-queries-D5duQ6QF.js';
1
+ import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-CxUeiT52.js';
2
+ export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-CxUeiT52.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, FieldType, evaluateFieldConditionGroup } from '@cmssy/types';
5
5
  import 'react';
@@ -76,6 +76,12 @@ interface GraphqlRequestOptions {
76
76
  fetch?: FetchLike;
77
77
  signal?: AbortSignal;
78
78
  headers?: Record<string, string>;
79
+ /**
80
+ * Route through the org-scoped public delivery path instead of the base
81
+ * `/graphql` endpoint. Set for unauthenticated public queries so the backend
82
+ * resolves the workspace from the URL rather than a global slug lookup.
83
+ */
84
+ public?: boolean;
79
85
  }
80
86
  declare function graphqlRequest<T>(config: CmssyClientConfig, query: string, variables: Record<string, unknown>, options?: GraphqlRequestOptions, label?: string): Promise<T>;
81
87
 
@@ -129,11 +135,13 @@ interface CmssyBlockProps {
129
135
  defaultLocale: string;
130
136
  blockMap: BlockMap;
131
137
  patchedContent?: Record<string, unknown>;
138
+ patchedStyle?: Record<string, unknown>;
139
+ patchedAdvanced?: Record<string, unknown>;
132
140
  editable?: boolean;
133
141
  layoutPosition?: string;
134
142
  context?: CmssyBlockContext;
135
143
  }
136
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
144
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
137
145
 
138
146
  interface UnknownBlockProps {
139
147
  type: string;
package/dist/index.js CHANGED
@@ -267,6 +267,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
267
267
  blockId: data.blockId,
268
268
  content: data.content,
269
269
  protocolVersion: PROTOCOL_VERSION,
270
+ ...isObject(data.style) ? { style: data.style } : {},
271
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
270
272
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
271
273
  } : null;
272
274
  case "cmssy:parent-ready":
@@ -278,6 +280,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
278
280
  blockId: data.blockId,
279
281
  blockType: data.blockType,
280
282
  content: data.content,
283
+ ...isObject(data.style) ? { style: data.style } : {},
284
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
281
285
  index: data.index
282
286
  } : null;
283
287
  case "cmssy:reorder":
@@ -314,6 +318,10 @@ function resolveApiUrl(apiUrl) {
314
318
  const fromEnv = env?.CMSSY_API_URL?.trim() ?? "";
315
319
  return fromEnv.length > 0 ? fromEnv : DEFAULT_CMSSY_API_URL;
316
320
  }
321
+ function resolvePublicUrl(config) {
322
+ const base = resolveApiUrl(config.apiUrl).replace(/\/graphql\/?$/, "");
323
+ return `${base}/public/${config.org}/${config.workspaceSlug}/graphql`;
324
+ }
317
325
  var PUBLIC_PAGE_QUERY = `query PublicPage($workspaceSlug: String!, $slug: String!, $previewSecret: String) {
318
326
  public {
319
327
  page {
@@ -410,7 +418,7 @@ async function fetchPage(config, path, options = {}) {
410
418
  headers["x-workspace-id"] = options.workspaceId;
411
419
  }
412
420
  }
413
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
421
+ const response = await doFetch(resolvePublicUrl(config), {
414
422
  method: "POST",
415
423
  headers,
416
424
  body: JSON.stringify({
@@ -459,7 +467,7 @@ async function fetchPageById(config, pageId, options = {}) {
459
467
  "cmssy: no fetch implementation available - pass options.fetch"
460
468
  );
461
469
  }
462
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
470
+ const response = await doFetch(resolvePublicUrl(config), {
463
471
  method: "POST",
464
472
  headers: { "content-type": "application/json" },
465
473
  body: JSON.stringify({
@@ -503,7 +511,7 @@ async function fetchPages(config, options = {}) {
503
511
  "cmssy: no fetch implementation available - pass options.fetch"
504
512
  );
505
513
  }
506
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
514
+ const response = await doFetch(resolvePublicUrl(config), {
507
515
  method: "POST",
508
516
  headers: { "content-type": "application/json" },
509
517
  body: JSON.stringify({
@@ -535,7 +543,7 @@ async function fetchPageMeta(config, path, options = {}) {
535
543
  "cmssy: no fetch implementation available - pass options.fetch"
536
544
  );
537
545
  }
538
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
546
+ const response = await doFetch(resolvePublicUrl(config), {
539
547
  method: "POST",
540
548
  headers: { "content-type": "application/json" },
541
549
  body: JSON.stringify({
@@ -569,7 +577,7 @@ async function fetchLayouts(config, path, options = {}) {
569
577
  }
570
578
  const trimmedSecret = options.previewSecret?.trim();
571
579
  const previewSecret = trimmedSecret ? trimmedSecret : null;
572
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
580
+ const response = await doFetch(resolvePublicUrl(config), {
573
581
  method: "POST",
574
582
  headers: { "content-type": "application/json" },
575
583
  body: JSON.stringify({
@@ -606,7 +614,8 @@ async function graphqlRequest(config, query, variables, options = {}, label = "r
606
614
  "cmssy: no fetch implementation available - pass options.fetch"
607
615
  );
608
616
  }
609
- const response = await doFetch(resolveApiUrl(config.apiUrl), {
617
+ const url = options.public ? resolvePublicUrl(config) : resolveApiUrl(config.apiUrl);
618
+ const response = await doFetch(url, {
610
619
  method: "POST",
611
620
  headers: { "content-type": "application/json", ...options.headers },
612
621
  body: JSON.stringify({ query, variables }),
@@ -639,20 +648,22 @@ async function graphqlRequest(config, query, variables, options = {}, label = "r
639
648
 
640
649
  // src/data/queries.ts
641
650
  var SITE_CONFIG_QUERY = `query PublicSiteConfig($workspaceSlug: String!) {
642
- publicSiteConfig(workspaceSlug: $workspaceSlug) {
643
- id
644
- workspaceId
645
- siteName
646
- defaultLanguage
647
- enabledLanguages
648
- enabledFeatures
649
- notFoundPageId
650
- previewUrl
651
- branding {
652
- brandName
653
- logoUrl
654
- faviconUrl
655
- ogImageUrl
651
+ public {
652
+ siteConfig(workspaceSlug: $workspaceSlug) {
653
+ id
654
+ workspaceId
655
+ siteName
656
+ defaultLanguage
657
+ enabledLanguages
658
+ enabledFeatures
659
+ notFoundPageId
660
+ previewUrl
661
+ branding {
662
+ brandName
663
+ logoUrl
664
+ faviconUrl
665
+ ogImageUrl
666
+ }
656
667
  }
657
668
  }
658
669
  }`;
@@ -698,10 +709,10 @@ async function fetchSiteConfig(config, options = {}) {
698
709
  config,
699
710
  SITE_CONFIG_QUERY,
700
711
  { workspaceSlug: config.workspaceSlug },
701
- options,
712
+ { ...options, public: true },
702
713
  "site config query"
703
714
  );
704
- return data.publicSiteConfig ?? null;
715
+ return data.public?.siteConfig ?? null;
705
716
  }
706
717
  async function resolveWorkspaceId(config, options = {}) {
707
718
  const siteConfig = await fetchSiteConfig(config, options);
@@ -804,7 +815,7 @@ var TTL_MS = 6e4;
804
815
  var MAX_ENTRIES = 64;
805
816
  var cache = /* @__PURE__ */ new Map();
806
817
  async function resolveSiteLocales(config, options) {
807
- const key = `${resolveApiUrl(config.apiUrl)}::${config.workspaceSlug}`;
818
+ const key = `${resolveApiUrl(config.apiUrl)}::${config.org}::${config.workspaceSlug}`;
808
819
  const cached = cache.get(key);
809
820
  if (cached && cached.expires > Date.now()) return cached.value;
810
821
  cache.delete(key);
@@ -814,10 +825,10 @@ async function resolveSiteLocales(config, options) {
814
825
  config,
815
826
  SITE_CONFIG_QUERY,
816
827
  { workspaceSlug: config.workspaceSlug },
817
- options,
828
+ { ...options, public: true },
818
829
  "site config"
819
830
  );
820
- const siteConfig = data.publicSiteConfig;
831
+ const siteConfig = data.public?.siteConfig ?? null;
821
832
  const defaultLocale = siteConfig?.defaultLanguage || "en";
822
833
  const enabled = siteConfig?.enabledLanguages ?? [];
823
834
  value = {
@@ -890,6 +901,8 @@ function CmssyBlock({
890
901
  defaultLocale,
891
902
  blockMap,
892
903
  patchedContent,
904
+ patchedStyle,
905
+ patchedAdvanced,
893
906
  editable,
894
907
  layoutPosition,
895
908
  context
@@ -897,6 +910,8 @@ function CmssyBlock({
897
910
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
898
911
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
899
912
  const content = patchedContent ? { ...base, ...patchedContent } : base;
913
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
914
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
900
915
  return /* @__PURE__ */ jsx(
901
916
  "div",
902
917
  {
@@ -907,12 +922,12 @@ function CmssyBlock({
907
922
  style: Component ? void 0 : { display: "none" },
908
923
  children: Component ? createElement(Component, {
909
924
  content,
910
- style: asBucket(block.style),
911
- advanced: asBucket(block.advanced),
925
+ style,
926
+ advanced,
912
927
  context
913
928
  }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
914
929
  }
915
930
  );
916
931
  }
917
932
 
918
- export { CmssyBlock, CmssyServerLayout, CmssyServerPage, DEFAULT_CMSSY_API_URL, FORM_QUERY, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, PROTOCOL_VERSION, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockContext, buildBlockMap, buildLocaleSwitchHref, collectFormIds, createCmssyClient, defineBlock, fetchLayouts, fetchPage, fetchPageById, fetchPageMeta, fetchPages, fetchSiteConfig, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, localizeHref, localizeHtmlLinks, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor, resolveApiUrl, resolveForms, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath };
933
+ export { CmssyBlock, CmssyServerLayout, CmssyServerPage, DEFAULT_CMSSY_API_URL, FORM_QUERY, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, PROTOCOL_VERSION, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockContext, buildBlockMap, buildLocaleSwitchHref, collectFormIds, createCmssyClient, defineBlock, fetchLayouts, fetchPage, fetchPageById, fetchPageMeta, fetchPages, fetchSiteConfig, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, localizeHref, localizeHtmlLinks, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor, resolveApiUrl, resolveForms, resolvePublicUrl, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "0.14.0",
3
+ "version": "0.17.0",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",