@cmssy/react 9.6.0 → 9.7.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/dist/client.cjs CHANGED
@@ -522,6 +522,8 @@ function CmssyBlock({
522
522
  patchedContent,
523
523
  patchedStyle,
524
524
  patchedAdvanced,
525
+ resolvedContent,
526
+ schema,
525
527
  editable,
526
528
  editMode,
527
529
  layoutPosition,
@@ -567,8 +569,9 @@ function CmssyBlock({
567
569
  )
568
570
  );
569
571
  }
570
- const base = core.getBlockContentForLanguage(block.content, locale, defaultLocale);
572
+ const base = resolvedContent ? { ...resolvedContent } : core.getBlockContentForLanguage(block.content, locale, defaultLocale);
571
573
  const content = patchedContent ? { ...base, ...patchedContent } : base;
574
+ if (schema) core.normalizeRelationContent(content, schema);
572
575
  const style = patchedStyle ? { ...core.asBucket(block.style), ...patchedStyle } : core.asBucket(block.style);
573
576
  const advanced = patchedAdvanced ? { ...core.asBucket(block.advanced), ...patchedAdvanced } : core.asBucket(block.advanced);
574
577
  return wrap(
@@ -598,7 +601,8 @@ function CmssyEditablePage({
598
601
  edit,
599
602
  category,
600
603
  forms,
601
- data
604
+ data,
605
+ resolvedContent
602
606
  }) {
603
607
  if (!Array.isArray(blocks)) {
604
608
  throw new Error(
@@ -617,7 +621,8 @@ function CmssyEditablePage({
617
621
  edit,
618
622
  category,
619
623
  forms,
620
- data
624
+ data,
625
+ resolvedContent
621
626
  }
622
627
  );
623
628
  }
@@ -630,7 +635,8 @@ function EditableBlocks({
630
635
  edit,
631
636
  category,
632
637
  forms,
633
- data
638
+ data,
639
+ resolvedContent
634
640
  }) {
635
641
  const blockMap = react.useMemo(() => buildBlockMap(blocks), [blocks]);
636
642
  const context = react.useMemo(
@@ -680,6 +686,8 @@ function EditableBlocks({
680
686
  patchedContent: patches[block.id],
681
687
  patchedStyle: patchesStyle[block.id],
682
688
  patchedAdvanced: patchesAdvanced[block.id],
689
+ resolvedContent: resolvedContent?.[block.id],
690
+ schema: bridgeConfig.schemas?.[block.type],
683
691
  blockMap,
684
692
  editable: true,
685
693
  context,
@@ -775,9 +783,14 @@ function CmssyEditableLayout({
775
783
  defaultLocale = "en",
776
784
  enabledLocales,
777
785
  edit,
778
- data
786
+ data,
787
+ resolvedContent
779
788
  }) {
780
789
  const blockMap = react.useMemo(() => buildBlockMap(blocks), [blocks]);
790
+ const schemas = react.useMemo(
791
+ () => edit.schemas ?? blocksToSchemas(blocks),
792
+ [edit.schemas, blocks]
793
+ );
781
794
  const layoutBlocks = react.useMemo(() => {
782
795
  const group = groups.find((g) => g.position === position);
783
796
  return group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
@@ -796,6 +809,8 @@ function CmssyEditableLayout({
796
809
  defaultLocale,
797
810
  blockMap,
798
811
  patchedContent: patches[block.id],
812
+ resolvedContent: resolvedContent?.[block.id],
813
+ schema: schemas[block.type],
799
814
  editMode: true,
800
815
  layoutPosition: position,
801
816
  context,
package/dist/client.d.cts CHANGED
@@ -48,8 +48,9 @@ interface CmssyEditablePageProps {
48
48
  category?: string;
49
49
  forms?: Record<string, CmssyFormDefinition>;
50
50
  data?: Record<string, unknown>;
51
+ resolvedContent?: Record<string, Record<string, unknown>>;
51
52
  }
52
- declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, data, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
53
+ declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, data, resolvedContent, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
53
54
 
54
55
  interface CmssyLazyEditorProps {
55
56
  page: CmssyPageData | null;
@@ -59,6 +60,7 @@ interface CmssyLazyEditorProps {
59
60
  edit: EditBridgeConfig;
60
61
  forms?: Record<string, CmssyFormDefinition>;
61
62
  data?: Record<string, unknown>;
63
+ resolvedContent?: Record<string, Record<string, unknown>>;
62
64
  load: () => Promise<{
63
65
  blocks: BlockDefinition[];
64
66
  category?: string;
@@ -75,8 +77,9 @@ interface CmssyEditableLayoutProps {
75
77
  enabledLocales?: string[];
76
78
  edit: EditBridgeConfig;
77
79
  data?: Record<string, unknown>;
80
+ resolvedContent?: Record<string, Record<string, unknown>>;
78
81
  }
79
- declare function CmssyEditableLayout({ groups, blocks, position, locale, defaultLocale, enabledLocales, edit, data, }: CmssyEditableLayoutProps): react_jsx_runtime.JSX.Element | null;
82
+ declare function CmssyEditableLayout({ groups, blocks, position, locale, defaultLocale, enabledLocales, edit, data, resolvedContent, }: CmssyEditableLayoutProps): react_jsx_runtime.JSX.Element | null;
80
83
 
81
84
  interface CmssyLazyLayoutProps {
82
85
  groups: CmssyLayoutGroup[];
@@ -86,6 +89,7 @@ interface CmssyLazyLayoutProps {
86
89
  enabledLocales?: string[];
87
90
  edit: EditBridgeConfig;
88
91
  data?: Record<string, unknown>;
92
+ resolvedContent?: Record<string, Record<string, unknown>>;
89
93
  load: () => Promise<{
90
94
  blocks: BlockDefinition[];
91
95
  }>;
package/dist/client.d.ts CHANGED
@@ -48,8 +48,9 @@ interface CmssyEditablePageProps {
48
48
  category?: string;
49
49
  forms?: Record<string, CmssyFormDefinition>;
50
50
  data?: Record<string, unknown>;
51
+ resolvedContent?: Record<string, Record<string, unknown>>;
51
52
  }
52
- declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, data, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
53
+ declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, data, resolvedContent, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
53
54
 
54
55
  interface CmssyLazyEditorProps {
55
56
  page: CmssyPageData | null;
@@ -59,6 +60,7 @@ interface CmssyLazyEditorProps {
59
60
  edit: EditBridgeConfig;
60
61
  forms?: Record<string, CmssyFormDefinition>;
61
62
  data?: Record<string, unknown>;
63
+ resolvedContent?: Record<string, Record<string, unknown>>;
62
64
  load: () => Promise<{
63
65
  blocks: BlockDefinition[];
64
66
  category?: string;
@@ -75,8 +77,9 @@ interface CmssyEditableLayoutProps {
75
77
  enabledLocales?: string[];
76
78
  edit: EditBridgeConfig;
77
79
  data?: Record<string, unknown>;
80
+ resolvedContent?: Record<string, Record<string, unknown>>;
78
81
  }
79
- declare function CmssyEditableLayout({ groups, blocks, position, locale, defaultLocale, enabledLocales, edit, data, }: CmssyEditableLayoutProps): react_jsx_runtime.JSX.Element | null;
82
+ declare function CmssyEditableLayout({ groups, blocks, position, locale, defaultLocale, enabledLocales, edit, data, resolvedContent, }: CmssyEditableLayoutProps): react_jsx_runtime.JSX.Element | null;
80
83
 
81
84
  interface CmssyLazyLayoutProps {
82
85
  groups: CmssyLayoutGroup[];
@@ -86,6 +89,7 @@ interface CmssyLazyLayoutProps {
86
89
  enabledLocales?: string[];
87
90
  edit: EditBridgeConfig;
88
91
  data?: Record<string, unknown>;
92
+ resolvedContent?: Record<string, Record<string, unknown>>;
89
93
  load: () => Promise<{
90
94
  blocks: BlockDefinition[];
91
95
  }>;
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { createContext, useState, useRef, useEffect, useMemo, useContext, useCallback, createElement } from 'react';
3
- import { fields, resolveInitialTarget, buildBlockContext, postToEditor, PROTOCOL_VERSION, parseEditorMessage, getBlockContentForLanguage, asBucket, toMinorUnits, formatPrice } from '@cmssy/core';
3
+ import { fields, resolveInitialTarget, buildBlockContext, postToEditor, PROTOCOL_VERSION, parseEditorMessage, getBlockContentForLanguage, normalizeRelationContent, asBucket, toMinorUnits, formatPrice } from '@cmssy/core';
4
4
  export { formatPrice, fractionDigits, fromMinorUnits, toMinorUnits } from '@cmssy/core';
5
5
  import { BlockErrorBoundary } from '@cmssy/react/block-error-boundary';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -521,6 +521,8 @@ function CmssyBlock({
521
521
  patchedContent,
522
522
  patchedStyle,
523
523
  patchedAdvanced,
524
+ resolvedContent,
525
+ schema,
524
526
  editable,
525
527
  editMode,
526
528
  layoutPosition,
@@ -566,8 +568,9 @@ function CmssyBlock({
566
568
  )
567
569
  );
568
570
  }
569
- const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
571
+ const base = resolvedContent ? { ...resolvedContent } : getBlockContentForLanguage(block.content, locale, defaultLocale);
570
572
  const content = patchedContent ? { ...base, ...patchedContent } : base;
573
+ if (schema) normalizeRelationContent(content, schema);
571
574
  const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
572
575
  const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
573
576
  return wrap(
@@ -597,7 +600,8 @@ function CmssyEditablePage({
597
600
  edit,
598
601
  category,
599
602
  forms,
600
- data
603
+ data,
604
+ resolvedContent
601
605
  }) {
602
606
  if (!Array.isArray(blocks)) {
603
607
  throw new Error(
@@ -616,7 +620,8 @@ function CmssyEditablePage({
616
620
  edit,
617
621
  category,
618
622
  forms,
619
- data
623
+ data,
624
+ resolvedContent
620
625
  }
621
626
  );
622
627
  }
@@ -629,7 +634,8 @@ function EditableBlocks({
629
634
  edit,
630
635
  category,
631
636
  forms,
632
- data
637
+ data,
638
+ resolvedContent
633
639
  }) {
634
640
  const blockMap = useMemo(() => buildBlockMap(blocks), [blocks]);
635
641
  const context = useMemo(
@@ -679,6 +685,8 @@ function EditableBlocks({
679
685
  patchedContent: patches[block.id],
680
686
  patchedStyle: patchesStyle[block.id],
681
687
  patchedAdvanced: patchesAdvanced[block.id],
688
+ resolvedContent: resolvedContent?.[block.id],
689
+ schema: bridgeConfig.schemas?.[block.type],
682
690
  blockMap,
683
691
  editable: true,
684
692
  context,
@@ -774,9 +782,14 @@ function CmssyEditableLayout({
774
782
  defaultLocale = "en",
775
783
  enabledLocales,
776
784
  edit,
777
- data
785
+ data,
786
+ resolvedContent
778
787
  }) {
779
788
  const blockMap = useMemo(() => buildBlockMap(blocks), [blocks]);
789
+ const schemas = useMemo(
790
+ () => edit.schemas ?? blocksToSchemas(blocks),
791
+ [edit.schemas, blocks]
792
+ );
780
793
  const layoutBlocks = useMemo(() => {
781
794
  const group = groups.find((g) => g.position === position);
782
795
  return group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
@@ -795,6 +808,8 @@ function CmssyEditableLayout({
795
808
  defaultLocale,
796
809
  blockMap,
797
810
  patchedContent: patches[block.id],
811
+ resolvedContent: resolvedContent?.[block.id],
812
+ schema: schemas[block.type],
798
813
  editMode: true,
799
814
  layoutPosition: position,
800
815
  context,
package/dist/index.cjs CHANGED
@@ -319,18 +319,20 @@ async function CmssyServerPage({
319
319
  }
320
320
  function collectBlockData(blocks, resolved, isPreview) {
321
321
  const data = {};
322
+ const content = {};
322
323
  blocks.forEach((block, index) => {
323
324
  const entry = resolved[index];
324
325
  if (!entry) return;
326
+ content[block.id] = entry.content;
325
327
  if (entry.error && isPreview) {
326
328
  data[block.id] = markBlockError(entry.error);
327
329
  } else if (entry.data !== void 0) {
328
330
  data[block.id] = entry.data;
329
331
  }
330
332
  });
331
- return data;
333
+ return { data, content };
332
334
  }
333
- async function resolveBlockData({
335
+ async function resolveEditorBlockData({
334
336
  page,
335
337
  blocks,
336
338
  locale,
@@ -340,7 +342,7 @@ async function resolveBlockData({
340
342
  isPreview = false,
341
343
  config
342
344
  }) {
343
- if (!page) return {};
345
+ if (!page) return { data: {}, content: {} };
344
346
  const loaderMap = buildLoaderMap(blocks);
345
347
  const context = core.buildBlockContext(
346
348
  locale,
@@ -360,7 +362,10 @@ async function resolveBlockData({
360
362
  );
361
363
  return collectBlockData(page.blocks, resolved, isPreview);
362
364
  }
363
- async function resolveLayoutBlockData({
365
+ async function resolveBlockData(options) {
366
+ return (await resolveEditorBlockData(options)).data;
367
+ }
368
+ async function resolveEditorLayoutBlockData({
364
369
  groups,
365
370
  blocks,
366
371
  position,
@@ -373,7 +378,7 @@ async function resolveLayoutBlockData({
373
378
  }) {
374
379
  const group = groups.find((g) => g.position === position);
375
380
  const layoutBlocks = group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
376
- if (layoutBlocks.length === 0) return {};
381
+ if (layoutBlocks.length === 0) return { data: {}, content: {} };
377
382
  const loaderMap = buildLoaderMap(blocks);
378
383
  const context = core.buildBlockContext(
379
384
  locale,
@@ -393,6 +398,9 @@ async function resolveLayoutBlockData({
393
398
  );
394
399
  return collectBlockData(layoutBlocks, resolved, isPreview);
395
400
  }
401
+ async function resolveLayoutBlockData(options) {
402
+ return (await resolveEditorLayoutBlockData(options)).data;
403
+ }
396
404
  async function CmssyServerLayout({
397
405
  groups,
398
406
  blocks,
@@ -443,6 +451,8 @@ function CmssyBlock({
443
451
  patchedContent,
444
452
  patchedStyle,
445
453
  patchedAdvanced,
454
+ resolvedContent,
455
+ schema,
446
456
  editable,
447
457
  editMode,
448
458
  layoutPosition,
@@ -488,8 +498,9 @@ function CmssyBlock({
488
498
  )
489
499
  );
490
500
  }
491
- const base = core.getBlockContentForLanguage(block.content, locale, defaultLocale);
501
+ const base = resolvedContent ? { ...resolvedContent } : core.getBlockContentForLanguage(block.content, locale, defaultLocale);
492
502
  const content = patchedContent ? { ...base, ...patchedContent } : base;
503
+ if (schema) core.normalizeRelationContent(content, schema);
493
504
  const style = patchedStyle ? { ...core.asBucket(block.style), ...patchedStyle } : core.asBucket(block.style);
494
505
  const advanced = patchedAdvanced ? { ...core.asBucket(block.advanced), ...patchedAdvanced } : core.asBucket(block.advanced);
495
506
  return wrap(
@@ -660,4 +671,6 @@ exports.blocksToSchemas = blocksToSchemas;
660
671
  exports.buildBlockMap = buildBlockMap;
661
672
  exports.defineBlock = defineBlock;
662
673
  exports.resolveBlockData = resolveBlockData;
674
+ exports.resolveEditorBlockData = resolveEditorBlockData;
675
+ exports.resolveEditorLayoutBlockData = resolveEditorLayoutBlockData;
663
676
  exports.resolveLayoutBlockData = resolveLayoutBlockData;
package/dist/index.d.cts CHANGED
@@ -3,6 +3,7 @@ export { AppToEditorMessage, BlockMeta, BlockPropsSchema, BlockRect, BlockSchema
3
3
  import { B as BlockDefinition, a as BlockMap } from './registry-Bfq4Pq18.cjs';
4
4
  export { b as BlockProps, c as blocksToMeta, d as blocksToSchemas, e as buildBlockMap, f as defineBlock } from './registry-Bfq4Pq18.cjs';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import { FieldDefinition } from '@cmssy/types';
6
7
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, evaluateFieldConditionGroup } from '@cmssy/types';
7
8
  import 'react';
8
9
 
@@ -33,6 +34,10 @@ interface CmssyServerPageProps {
33
34
  */
34
35
  declare function CmssyServerPage({ page, blocks, locale: localeProp, defaultLocale: defaultLocaleProp, enabledLocales: enabledLocalesProp, config, forms, auth, workspace, editMode, }: CmssyServerPageProps): Promise<react_jsx_runtime.JSX.Element | null>;
35
36
 
37
+ interface EditorBlockData {
38
+ data: Record<string, unknown>;
39
+ content: Record<string, Record<string, unknown>>;
40
+ }
36
41
  interface ResolveBlockDataOptions {
37
42
  page: CmssyPageData | null;
38
43
  blocks: BlockDefinition[];
@@ -44,7 +49,8 @@ interface ResolveBlockDataOptions {
44
49
  /** Workspace the relation records are read from. No config, no resolution. */
45
50
  config?: CmssyClientConfig;
46
51
  }
47
- declare function resolveBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
52
+ declare function resolveEditorBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<EditorBlockData>;
53
+ declare function resolveBlockData(options: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
48
54
  interface ResolveLayoutBlockDataOptions {
49
55
  groups: CmssyLayoutGroup[];
50
56
  blocks: BlockDefinition[];
@@ -57,7 +63,8 @@ interface ResolveLayoutBlockDataOptions {
57
63
  /** Workspace the relation records are read from. No config, no resolution. */
58
64
  config?: CmssyClientConfig;
59
65
  }
60
- declare function resolveLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
66
+ declare function resolveEditorLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<EditorBlockData>;
67
+ declare function resolveLayoutBlockData(options: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
61
68
 
62
69
  interface CmssyServerLayoutProps {
63
70
  groups: CmssyLayoutGroup[];
@@ -90,17 +97,21 @@ interface CmssyBlockProps {
90
97
  patchedContent?: Record<string, unknown>;
91
98
  patchedStyle?: Record<string, unknown>;
92
99
  patchedAdvanced?: Record<string, unknown>;
100
+ /** Server-resolved content for this block (locale flattened, relations resolved). */
101
+ resolvedContent?: Record<string, unknown>;
102
+ /** The block's field schema; lets the client render coerce raw relation values. */
103
+ schema?: Record<string, FieldDefinition>;
93
104
  editable?: boolean;
94
105
  editMode?: boolean;
95
106
  layoutPosition?: string;
96
107
  context?: CmssyBlockContext;
97
108
  data?: unknown;
98
109
  }
99
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, editMode, layoutPosition, context, data, }: CmssyBlockProps): react_jsx_runtime.JSX.Element | null;
110
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, resolvedContent, schema, editable, editMode, layoutPosition, context, data, }: CmssyBlockProps): react_jsx_runtime.JSX.Element | null;
100
111
 
101
112
  interface UnknownBlockProps {
102
113
  type: string;
103
114
  }
104
115
  declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
105
116
 
106
- export { BlockDefinition, BlockMap, CmssyBlock, type CmssyBlockProps, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, UnknownBlock, type UnknownBlockProps, resolveBlockData, resolveLayoutBlockData };
117
+ export { BlockDefinition, BlockMap, CmssyBlock, type CmssyBlockProps, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type EditorBlockData, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, UnknownBlock, type UnknownBlockProps, resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { AppToEditorMessage, BlockMeta, BlockPropsSchema, BlockRect, BlockSchema
3
3
  import { B as BlockDefinition, a as BlockMap } from './registry-Bfq4Pq18.js';
4
4
  export { b as BlockProps, c as blocksToMeta, d as blocksToSchemas, e as buildBlockMap, f as defineBlock } from './registry-Bfq4Pq18.js';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import { FieldDefinition } from '@cmssy/types';
6
7
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, evaluateFieldConditionGroup } from '@cmssy/types';
7
8
  import 'react';
8
9
 
@@ -33,6 +34,10 @@ interface CmssyServerPageProps {
33
34
  */
34
35
  declare function CmssyServerPage({ page, blocks, locale: localeProp, defaultLocale: defaultLocaleProp, enabledLocales: enabledLocalesProp, config, forms, auth, workspace, editMode, }: CmssyServerPageProps): Promise<react_jsx_runtime.JSX.Element | null>;
35
36
 
37
+ interface EditorBlockData {
38
+ data: Record<string, unknown>;
39
+ content: Record<string, Record<string, unknown>>;
40
+ }
36
41
  interface ResolveBlockDataOptions {
37
42
  page: CmssyPageData | null;
38
43
  blocks: BlockDefinition[];
@@ -44,7 +49,8 @@ interface ResolveBlockDataOptions {
44
49
  /** Workspace the relation records are read from. No config, no resolution. */
45
50
  config?: CmssyClientConfig;
46
51
  }
47
- declare function resolveBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
52
+ declare function resolveEditorBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<EditorBlockData>;
53
+ declare function resolveBlockData(options: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
48
54
  interface ResolveLayoutBlockDataOptions {
49
55
  groups: CmssyLayoutGroup[];
50
56
  blocks: BlockDefinition[];
@@ -57,7 +63,8 @@ interface ResolveLayoutBlockDataOptions {
57
63
  /** Workspace the relation records are read from. No config, no resolution. */
58
64
  config?: CmssyClientConfig;
59
65
  }
60
- declare function resolveLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
66
+ declare function resolveEditorLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<EditorBlockData>;
67
+ declare function resolveLayoutBlockData(options: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
61
68
 
62
69
  interface CmssyServerLayoutProps {
63
70
  groups: CmssyLayoutGroup[];
@@ -90,17 +97,21 @@ interface CmssyBlockProps {
90
97
  patchedContent?: Record<string, unknown>;
91
98
  patchedStyle?: Record<string, unknown>;
92
99
  patchedAdvanced?: Record<string, unknown>;
100
+ /** Server-resolved content for this block (locale flattened, relations resolved). */
101
+ resolvedContent?: Record<string, unknown>;
102
+ /** The block's field schema; lets the client render coerce raw relation values. */
103
+ schema?: Record<string, FieldDefinition>;
93
104
  editable?: boolean;
94
105
  editMode?: boolean;
95
106
  layoutPosition?: string;
96
107
  context?: CmssyBlockContext;
97
108
  data?: unknown;
98
109
  }
99
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, editMode, layoutPosition, context, data, }: CmssyBlockProps): react_jsx_runtime.JSX.Element | null;
110
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, resolvedContent, schema, editable, editMode, layoutPosition, context, data, }: CmssyBlockProps): react_jsx_runtime.JSX.Element | null;
100
111
 
101
112
  interface UnknownBlockProps {
102
113
  type: string;
103
114
  }
104
115
  declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
105
116
 
106
- export { BlockDefinition, BlockMap, CmssyBlock, type CmssyBlockProps, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, UnknownBlock, type UnknownBlockProps, resolveBlockData, resolveLayoutBlockData };
117
+ export { BlockDefinition, BlockMap, CmssyBlock, type CmssyBlockProps, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type EditorBlockData, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, UnknownBlock, type UnknownBlockProps, resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { buildBlockContext, getBlockContentForLanguage, asBucket, resolveSiteLocales, resolveRelationContent } from '@cmssy/core';
1
+ import { buildBlockContext, getBlockContentForLanguage, normalizeRelationContent, asBucket, resolveSiteLocales, resolveRelationContent } from '@cmssy/core';
2
2
  export { CmssyRequestError, DEFAULT_CMSSY_API_URL, FORM_QUERY, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, PROTOCOL_VERSION, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, buildBlockContext, buildLocaleSwitchHref, collectFormIds, createCmssyClient, fetchLayouts, fetchPage, fetchPageById, fetchPageMeta, fetchPages, fetchSiteConfig, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, localizeHref, localizeHtmlLinks, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor, resolveApiUrl, resolveForms, resolvePublicUrl, resolveSiteLocales, resolveWorkspaceId, splitLocaleFromPath } from '@cmssy/core';
3
3
  import { createElement } from 'react';
4
4
  import { BlockErrorBoundary } from '@cmssy/react/block-error-boundary';
@@ -318,18 +318,20 @@ async function CmssyServerPage({
318
318
  }
319
319
  function collectBlockData(blocks, resolved, isPreview) {
320
320
  const data = {};
321
+ const content = {};
321
322
  blocks.forEach((block, index) => {
322
323
  const entry = resolved[index];
323
324
  if (!entry) return;
325
+ content[block.id] = entry.content;
324
326
  if (entry.error && isPreview) {
325
327
  data[block.id] = markBlockError(entry.error);
326
328
  } else if (entry.data !== void 0) {
327
329
  data[block.id] = entry.data;
328
330
  }
329
331
  });
330
- return data;
332
+ return { data, content };
331
333
  }
332
- async function resolveBlockData({
334
+ async function resolveEditorBlockData({
333
335
  page,
334
336
  blocks,
335
337
  locale,
@@ -339,7 +341,7 @@ async function resolveBlockData({
339
341
  isPreview = false,
340
342
  config
341
343
  }) {
342
- if (!page) return {};
344
+ if (!page) return { data: {}, content: {} };
343
345
  const loaderMap = buildLoaderMap(blocks);
344
346
  const context = buildBlockContext(
345
347
  locale,
@@ -359,7 +361,10 @@ async function resolveBlockData({
359
361
  );
360
362
  return collectBlockData(page.blocks, resolved, isPreview);
361
363
  }
362
- async function resolveLayoutBlockData({
364
+ async function resolveBlockData(options) {
365
+ return (await resolveEditorBlockData(options)).data;
366
+ }
367
+ async function resolveEditorLayoutBlockData({
363
368
  groups,
364
369
  blocks,
365
370
  position,
@@ -372,7 +377,7 @@ async function resolveLayoutBlockData({
372
377
  }) {
373
378
  const group = groups.find((g) => g.position === position);
374
379
  const layoutBlocks = group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
375
- if (layoutBlocks.length === 0) return {};
380
+ if (layoutBlocks.length === 0) return { data: {}, content: {} };
376
381
  const loaderMap = buildLoaderMap(blocks);
377
382
  const context = buildBlockContext(
378
383
  locale,
@@ -392,6 +397,9 @@ async function resolveLayoutBlockData({
392
397
  );
393
398
  return collectBlockData(layoutBlocks, resolved, isPreview);
394
399
  }
400
+ async function resolveLayoutBlockData(options) {
401
+ return (await resolveEditorLayoutBlockData(options)).data;
402
+ }
395
403
  async function CmssyServerLayout({
396
404
  groups,
397
405
  blocks,
@@ -442,6 +450,8 @@ function CmssyBlock({
442
450
  patchedContent,
443
451
  patchedStyle,
444
452
  patchedAdvanced,
453
+ resolvedContent,
454
+ schema,
445
455
  editable,
446
456
  editMode,
447
457
  layoutPosition,
@@ -487,8 +497,9 @@ function CmssyBlock({
487
497
  )
488
498
  );
489
499
  }
490
- const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
500
+ const base = resolvedContent ? { ...resolvedContent } : getBlockContentForLanguage(block.content, locale, defaultLocale);
491
501
  const content = patchedContent ? { ...base, ...patchedContent } : base;
502
+ if (schema) normalizeRelationContent(content, schema);
492
503
  const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
493
504
  const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
494
505
  return wrap(
@@ -510,4 +521,4 @@ function CmssyBlock({
510
521
  );
511
522
  }
512
523
 
513
- export { CmssyBlock, CmssyServerLayout, CmssyServerPage, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockMap, defineBlock, resolveBlockData, resolveLayoutBlockData };
524
+ export { CmssyBlock, CmssyServerLayout, CmssyServerPage, UnknownBlock, blocksToMeta, blocksToSchemas, buildBlockMap, defineBlock, resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "9.6.0",
3
+ "version": "9.7.0",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -62,7 +62,7 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@cmssy/types": "0.29.0",
65
- "@cmssy/core": "9.6.0"
65
+ "@cmssy/core": "9.7.0"
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsup",