@cmssy/react 0.1.4 → 0.1.6

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
@@ -304,18 +304,41 @@ function blockElements() {
304
304
  )
305
305
  ).filter(visible);
306
306
  }
307
- function computeDropTarget(clientY) {
308
- const els = blockElements();
309
- for (let i = 0; i < els.length; i++) {
310
- const r = els[i].getBoundingClientRect();
311
- if (clientY < r.top + r.height / 2) {
312
- return { index: i, y: r.top };
313
- }
314
- }
315
- const last = els[els.length - 1];
307
+ function createDropTargetResolver() {
308
+ let cache = null;
309
+ const build = () => {
310
+ const els = blockElements();
311
+ const scrollY = window.scrollY;
312
+ let absLastBottom = scrollY;
313
+ const blocks = els.map((el, index) => {
314
+ const r = el.getBoundingClientRect();
315
+ absLastBottom = r.bottom + scrollY;
316
+ return {
317
+ index,
318
+ absTop: r.top + scrollY,
319
+ absMid: r.top + scrollY + r.height / 2
320
+ };
321
+ });
322
+ cache = { blocks, absLastBottom };
323
+ };
316
324
  return {
317
- index: els.length,
318
- y: last ? last.getBoundingClientRect().bottom : 0
325
+ resolve(clientY) {
326
+ if (!cache) build();
327
+ const scrollY = window.scrollY;
328
+ const pageY = clientY + scrollY;
329
+ for (const block of cache.blocks) {
330
+ if (pageY < block.absMid) {
331
+ return { index: block.index, y: block.absTop - scrollY };
332
+ }
333
+ }
334
+ return {
335
+ index: cache.blocks.length,
336
+ y: cache.absLastBottom - scrollY
337
+ };
338
+ },
339
+ invalidate() {
340
+ cache = null;
341
+ }
319
342
  };
320
343
  }
321
344
  function useDragAgent(config) {
@@ -330,6 +353,7 @@ function useDragAgent(config) {
330
353
  }
331
354
  let movingId = null;
332
355
  let lastDropY = null;
356
+ const resolver = createDropTargetResolver();
333
357
  const updateDropY = (y) => {
334
358
  if (y === lastDropY) return;
335
359
  lastDropY = y;
@@ -340,21 +364,23 @@ function useDragAgent(config) {
340
364
  const id = blockEl?.getAttribute("data-block-id");
341
365
  if (!id || !event.dataTransfer) return;
342
366
  movingId = id;
367
+ resolver.invalidate();
343
368
  event.dataTransfer.setData(MOVE_MIME, id);
344
369
  event.dataTransfer.effectAllowed = "move";
345
370
  };
346
371
  const onDragOver = (event) => {
347
372
  if (!movingId) return;
348
373
  event.preventDefault();
349
- updateDropY(computeDropTarget(event.clientY).y);
374
+ updateDropY(resolver.resolve(event.clientY).y);
350
375
  };
351
376
  const onDrop = (event) => {
352
377
  if (!movingId) return;
353
378
  event.preventDefault();
354
- const { index } = computeDropTarget(event.clientY);
379
+ const { index } = resolver.resolve(event.clientY);
355
380
  const blockId = movingId;
356
381
  movingId = null;
357
382
  updateDropY(null);
383
+ resolver.invalidate();
358
384
  try {
359
385
  postToEditor(window.parent, editorOrigin, {
360
386
  type: "cmssy:move",
@@ -368,6 +394,7 @@ function useDragAgent(config) {
368
394
  const onDragEnd = () => {
369
395
  movingId = null;
370
396
  updateDropY(null);
397
+ resolver.invalidate();
371
398
  };
372
399
  const onMessage = (event) => {
373
400
  if (event.source && event.source !== window.parent) return;
@@ -385,7 +412,7 @@ function useDragAgent(config) {
385
412
  } else if (message.y > window.innerHeight - edge) {
386
413
  window.scrollBy(0, step);
387
414
  }
388
- const { index, y } = computeDropTarget(message.y);
415
+ const { index, y } = resolver.resolve(message.y);
389
416
  updateDropY(y);
390
417
  try {
391
418
  postToEditor(window.parent, editorOrigin, {
@@ -397,6 +424,7 @@ function useDragAgent(config) {
397
424
  }
398
425
  } else if (message.type === "cmssy:drag-end") {
399
426
  updateDropY(null);
427
+ resolver.invalidate();
400
428
  }
401
429
  };
402
430
  document.addEventListener("dragstart", onDragStart);
@@ -416,14 +444,15 @@ function useDragAgent(config) {
416
444
  }
417
445
 
418
446
  // src/components/block-context.ts
419
- function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview) {
447
+ function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
420
448
  return {
421
449
  locale: {
422
450
  current: locale,
423
451
  default: defaultLocale,
424
452
  enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
425
453
  },
426
- isPreview: isPreview ?? false
454
+ isPreview: isPreview ?? false,
455
+ forms
427
456
  };
428
457
  }
429
458
 
@@ -492,7 +521,8 @@ function CmssyEditablePage({
492
521
  defaultLocale = "en",
493
522
  enabledLocales,
494
523
  edit,
495
- category
524
+ category,
525
+ forms
496
526
  }) {
497
527
  if (!Array.isArray(blocks)) {
498
528
  throw new Error(
@@ -509,7 +539,8 @@ function CmssyEditablePage({
509
539
  defaultLocale,
510
540
  enabledLocales,
511
541
  edit,
512
- category
542
+ category,
543
+ forms
513
544
  }
514
545
  );
515
546
  }
@@ -520,12 +551,13 @@ function EditableBlocks({
520
551
  defaultLocale,
521
552
  enabledLocales,
522
553
  edit,
523
- category
554
+ category,
555
+ forms
524
556
  }) {
525
557
  const blockMap = react.useMemo(() => buildBlockMap(blocks), [blocks]);
526
558
  const context = react.useMemo(
527
- () => buildBlockContext(locale, defaultLocale, enabledLocales, true),
528
- [locale, defaultLocale, enabledLocales]
559
+ () => buildBlockContext(locale, defaultLocale, enabledLocales, true, forms),
560
+ [locale, defaultLocale, enabledLocales, forms]
529
561
  );
530
562
  const bridgeConfig = react.useMemo(
531
563
  () => ({
package/dist/client.d.cts CHANGED
@@ -1,5 +1,5 @@
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 CmssyLayoutGroup } from './registry-suRGkEQs.cjs';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-BaFQ2k7r.cjs';
3
3
  import 'react';
4
4
 
5
5
  interface EditBridgeConfig {
@@ -38,8 +38,9 @@ interface CmssyEditablePageProps {
38
38
  enabledLocales?: string[];
39
39
  edit: EditBridgeConfig;
40
40
  category?: string;
41
+ forms?: Record<string, CmssyFormDefinition>;
41
42
  }
42
- declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
43
+ declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
43
44
 
44
45
  interface CmssyLazyEditorProps {
45
46
  page: CmssyPageData | null;
@@ -47,6 +48,7 @@ interface CmssyLazyEditorProps {
47
48
  defaultLocale?: string;
48
49
  enabledLocales?: string[];
49
50
  edit: EditBridgeConfig;
51
+ forms?: Record<string, CmssyFormDefinition>;
50
52
  load: () => Promise<{
51
53
  blocks: BlockDefinition[];
52
54
  category?: string;
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
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 CmssyLayoutGroup } from './registry-suRGkEQs.js';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup } from './registry-BaFQ2k7r.js';
3
3
  import 'react';
4
4
 
5
5
  interface EditBridgeConfig {
@@ -38,8 +38,9 @@ interface CmssyEditablePageProps {
38
38
  enabledLocales?: string[];
39
39
  edit: EditBridgeConfig;
40
40
  category?: string;
41
+ forms?: Record<string, CmssyFormDefinition>;
41
42
  }
42
- declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
43
+ declare function CmssyEditablePage({ page, blocks, locale, defaultLocale, enabledLocales, edit, category, forms, }: CmssyEditablePageProps): react_jsx_runtime.JSX.Element | null;
43
44
 
44
45
  interface CmssyLazyEditorProps {
45
46
  page: CmssyPageData | null;
@@ -47,6 +48,7 @@ interface CmssyLazyEditorProps {
47
48
  defaultLocale?: string;
48
49
  enabledLocales?: string[];
49
50
  edit: EditBridgeConfig;
51
+ forms?: Record<string, CmssyFormDefinition>;
50
52
  load: () => Promise<{
51
53
  blocks: BlockDefinition[];
52
54
  category?: string;
package/dist/client.js CHANGED
@@ -302,18 +302,41 @@ function blockElements() {
302
302
  )
303
303
  ).filter(visible);
304
304
  }
305
- function computeDropTarget(clientY) {
306
- const els = blockElements();
307
- for (let i = 0; i < els.length; i++) {
308
- const r = els[i].getBoundingClientRect();
309
- if (clientY < r.top + r.height / 2) {
310
- return { index: i, y: r.top };
311
- }
312
- }
313
- const last = els[els.length - 1];
305
+ function createDropTargetResolver() {
306
+ let cache = null;
307
+ const build = () => {
308
+ const els = blockElements();
309
+ const scrollY = window.scrollY;
310
+ let absLastBottom = scrollY;
311
+ const blocks = els.map((el, index) => {
312
+ const r = el.getBoundingClientRect();
313
+ absLastBottom = r.bottom + scrollY;
314
+ return {
315
+ index,
316
+ absTop: r.top + scrollY,
317
+ absMid: r.top + scrollY + r.height / 2
318
+ };
319
+ });
320
+ cache = { blocks, absLastBottom };
321
+ };
314
322
  return {
315
- index: els.length,
316
- y: last ? last.getBoundingClientRect().bottom : 0
323
+ resolve(clientY) {
324
+ if (!cache) build();
325
+ const scrollY = window.scrollY;
326
+ const pageY = clientY + scrollY;
327
+ for (const block of cache.blocks) {
328
+ if (pageY < block.absMid) {
329
+ return { index: block.index, y: block.absTop - scrollY };
330
+ }
331
+ }
332
+ return {
333
+ index: cache.blocks.length,
334
+ y: cache.absLastBottom - scrollY
335
+ };
336
+ },
337
+ invalidate() {
338
+ cache = null;
339
+ }
317
340
  };
318
341
  }
319
342
  function useDragAgent(config) {
@@ -328,6 +351,7 @@ function useDragAgent(config) {
328
351
  }
329
352
  let movingId = null;
330
353
  let lastDropY = null;
354
+ const resolver = createDropTargetResolver();
331
355
  const updateDropY = (y) => {
332
356
  if (y === lastDropY) return;
333
357
  lastDropY = y;
@@ -338,21 +362,23 @@ function useDragAgent(config) {
338
362
  const id = blockEl?.getAttribute("data-block-id");
339
363
  if (!id || !event.dataTransfer) return;
340
364
  movingId = id;
365
+ resolver.invalidate();
341
366
  event.dataTransfer.setData(MOVE_MIME, id);
342
367
  event.dataTransfer.effectAllowed = "move";
343
368
  };
344
369
  const onDragOver = (event) => {
345
370
  if (!movingId) return;
346
371
  event.preventDefault();
347
- updateDropY(computeDropTarget(event.clientY).y);
372
+ updateDropY(resolver.resolve(event.clientY).y);
348
373
  };
349
374
  const onDrop = (event) => {
350
375
  if (!movingId) return;
351
376
  event.preventDefault();
352
- const { index } = computeDropTarget(event.clientY);
377
+ const { index } = resolver.resolve(event.clientY);
353
378
  const blockId = movingId;
354
379
  movingId = null;
355
380
  updateDropY(null);
381
+ resolver.invalidate();
356
382
  try {
357
383
  postToEditor(window.parent, editorOrigin, {
358
384
  type: "cmssy:move",
@@ -366,6 +392,7 @@ function useDragAgent(config) {
366
392
  const onDragEnd = () => {
367
393
  movingId = null;
368
394
  updateDropY(null);
395
+ resolver.invalidate();
369
396
  };
370
397
  const onMessage = (event) => {
371
398
  if (event.source && event.source !== window.parent) return;
@@ -383,7 +410,7 @@ function useDragAgent(config) {
383
410
  } else if (message.y > window.innerHeight - edge) {
384
411
  window.scrollBy(0, step);
385
412
  }
386
- const { index, y } = computeDropTarget(message.y);
413
+ const { index, y } = resolver.resolve(message.y);
387
414
  updateDropY(y);
388
415
  try {
389
416
  postToEditor(window.parent, editorOrigin, {
@@ -395,6 +422,7 @@ function useDragAgent(config) {
395
422
  }
396
423
  } else if (message.type === "cmssy:drag-end") {
397
424
  updateDropY(null);
425
+ resolver.invalidate();
398
426
  }
399
427
  };
400
428
  document.addEventListener("dragstart", onDragStart);
@@ -414,14 +442,15 @@ function useDragAgent(config) {
414
442
  }
415
443
 
416
444
  // src/components/block-context.ts
417
- function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview) {
445
+ function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
418
446
  return {
419
447
  locale: {
420
448
  current: locale,
421
449
  default: defaultLocale,
422
450
  enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
423
451
  },
424
- isPreview: isPreview ?? false
452
+ isPreview: isPreview ?? false,
453
+ forms
425
454
  };
426
455
  }
427
456
 
@@ -490,7 +519,8 @@ function CmssyEditablePage({
490
519
  defaultLocale = "en",
491
520
  enabledLocales,
492
521
  edit,
493
- category
522
+ category,
523
+ forms
494
524
  }) {
495
525
  if (!Array.isArray(blocks)) {
496
526
  throw new Error(
@@ -507,7 +537,8 @@ function CmssyEditablePage({
507
537
  defaultLocale,
508
538
  enabledLocales,
509
539
  edit,
510
- category
540
+ category,
541
+ forms
511
542
  }
512
543
  );
513
544
  }
@@ -518,12 +549,13 @@ function EditableBlocks({
518
549
  defaultLocale,
519
550
  enabledLocales,
520
551
  edit,
521
- category
552
+ category,
553
+ forms
522
554
  }) {
523
555
  const blockMap = useMemo(() => buildBlockMap(blocks), [blocks]);
524
556
  const context = useMemo(
525
- () => buildBlockContext(locale, defaultLocale, enabledLocales, true),
526
- [locale, defaultLocale, enabledLocales]
557
+ () => buildBlockContext(locale, defaultLocale, enabledLocales, true, forms),
558
+ [locale, defaultLocale, enabledLocales, forms]
527
559
  );
528
560
  const bridgeConfig = useMemo(
529
561
  () => ({
package/dist/index.cjs CHANGED
@@ -61,14 +61,15 @@ function blocksToMeta(blocks, defaults = {}) {
61
61
  }
62
62
 
63
63
  // src/components/block-context.ts
64
- function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview) {
64
+ function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
65
65
  return {
66
66
  locale: {
67
67
  current: locale,
68
68
  default: defaultLocale,
69
69
  enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
70
70
  },
71
- isPreview: isPreview ?? false
71
+ isPreview: isPreview ?? false,
72
+ forms
72
73
  };
73
74
  }
74
75
 
@@ -128,11 +129,18 @@ function CmssyServerPage({
128
129
  blocks,
129
130
  locale = "en",
130
131
  defaultLocale = "en",
131
- enabledLocales
132
+ enabledLocales,
133
+ forms
132
134
  }) {
133
135
  if (!page) return null;
134
136
  const map = buildBlockMap(blocks);
135
- const context = buildBlockContext(locale, defaultLocale, enabledLocales);
137
+ const context = buildBlockContext(
138
+ locale,
139
+ defaultLocale,
140
+ enabledLocales,
141
+ false,
142
+ forms
143
+ );
136
144
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: page.blocks.map(
137
145
  (block) => renderResolvedBlock(block, map, locale, defaultLocale, context)
138
146
  ) });
@@ -501,6 +509,44 @@ function createCmssyClient(config) {
501
509
  }
502
510
  };
503
511
  }
512
+
513
+ // src/data/resolve-forms.ts
514
+ function collectFormIds(blocks, locale, defaultLocale) {
515
+ const ids = /* @__PURE__ */ new Set();
516
+ for (const block of blocks) {
517
+ const content = getBlockContentForLanguage(
518
+ block.content,
519
+ locale,
520
+ defaultLocale
521
+ );
522
+ const formId = content.formId;
523
+ if (typeof formId === "string" && formId.trim()) ids.add(formId);
524
+ }
525
+ return [...ids];
526
+ }
527
+ async function resolveForms(config, blocks, locale, defaultLocale, options) {
528
+ const ids = collectFormIds(blocks, locale, defaultLocale);
529
+ if (ids.length === 0) return {};
530
+ const client = createCmssyClient(config);
531
+ const entries = await Promise.all(
532
+ ids.map(async (id) => {
533
+ try {
534
+ const data = await client.queryScoped(FORM_QUERY, { formId: id }, options);
535
+ return [id, data.publicForm];
536
+ } catch (err) {
537
+ if (typeof console !== "undefined") {
538
+ console.warn(`[cmssy] failed to resolve form ${id}`, err);
539
+ }
540
+ return [id, null];
541
+ }
542
+ })
543
+ );
544
+ const forms = {};
545
+ for (const [id, def] of entries) {
546
+ if (def) forms[id] = def;
547
+ }
548
+ return forms;
549
+ }
504
550
  function CmssyBlock({
505
551
  block,
506
552
  locale,
@@ -541,6 +587,7 @@ exports.blocksToMeta = blocksToMeta;
541
587
  exports.blocksToSchemas = blocksToSchemas;
542
588
  exports.buildBlockContext = buildBlockContext;
543
589
  exports.buildBlockMap = buildBlockMap;
590
+ exports.collectFormIds = collectFormIds;
544
591
  exports.createCmssyClient = createCmssyClient;
545
592
  exports.defineBlock = defineBlock;
546
593
  exports.fetchLayouts = fetchLayouts;
@@ -553,3 +600,4 @@ exports.normalizeOrigin = normalizeOrigin;
553
600
  exports.normalizeSlug = normalizeSlug;
554
601
  exports.parseEditorMessage = parseEditorMessage;
555
602
  exports.postToEditor = postToEditor;
603
+ exports.resolveForms = resolveForms;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, d as FetchLike, e as CmssyClientConfig, R as RawBlock, f as BlockMap, g as CmssyBlockContext } from './registry-suRGkEQs.cjs';
2
- export { a as BlockMeta, h as BlockRect, B as BlockSchema, i as BoundsMessage, j as ClickMessage, k as CmssyLocaleContext, l as FetchLikeResponse, m as FetchPageOptions, n as FieldType, P as PROTOCOL_VERSION, o as ParentReadyMessage, p as PatchMessage, q as RawLayoutBlock, r as ReadyMessage, S as SelectMessage, s as blocksToMeta, t as blocksToSchemas, u as buildBlockContext, v as buildBlockMap, w as defineBlock, x as fetchLayouts, y as fetchPage, z as isProtocolCompatible, D as normalizeSlug } from './registry-suRGkEQs.cjs';
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-BaFQ2k7r.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-BaFQ2k7r.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import 'react';
5
5
 
@@ -28,8 +28,10 @@ interface CmssyServerPageProps {
28
28
  defaultLocale?: string;
29
29
  /** All languages enabled on the workspace; exposed to blocks via context.locale.enabled. */
30
30
  enabledLocales?: string[];
31
+ /** Form definitions referenced by page blocks, exposed via context.forms. */
32
+ forms?: Record<string, CmssyFormDefinition>;
31
33
  }
32
- declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, }: CmssyServerPageProps): react_jsx_runtime.JSX.Element | null;
34
+ declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, forms, }: CmssyServerPageProps): react_jsx_runtime.JSX.Element | null;
33
35
 
34
36
  interface CmssyServerLayoutProps {
35
37
  groups: CmssyLayoutGroup[];
@@ -69,94 +71,8 @@ interface CmssyClient {
69
71
  }
70
72
  declare function createCmssyClient(config: CmssyClientConfig): CmssyClient;
71
73
 
72
- interface CmssyBranding {
73
- brandName: string | null;
74
- logoUrl: string | null;
75
- faviconUrl: string | null;
76
- ogImageUrl: string | null;
77
- }
78
- interface CmssySiteConfig {
79
- id: string;
80
- workspaceId: string;
81
- siteName: unknown;
82
- defaultLanguage: string | null;
83
- enabledLanguages: string[];
84
- enabledFeatures: string[];
85
- notFoundPageId: string | null;
86
- previewUrl: string | null;
87
- branding: CmssyBranding | null;
88
- }
89
- 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}";
90
- interface CmssyModelDefinition {
91
- id: string;
92
- name: string;
93
- slug: string;
94
- description: string | null;
95
- icon: string | null;
96
- color: string | null;
97
- displayField: string | null;
98
- recordCount: number | null;
99
- }
100
- interface CmssyModelRecord {
101
- id: string;
102
- modelId: string;
103
- data: Record<string, unknown>;
104
- status: string | null;
105
- createdAt: string | null;
106
- updatedAt: string | null;
107
- }
108
- interface CmssyRecordList {
109
- items: CmssyModelRecord[];
110
- total: number;
111
- hasMore: boolean;
112
- }
113
- declare const MODEL_DEFINITIONS_QUERY = "query PublicModelDefinitions($workspaceId: String!) {\n publicModelDefinitions(workspaceId: $workspaceId) {\n id name slug description icon color displayField recordCount\n }\n}";
114
- declare const MODEL_RECORDS_QUERY = "query PublicModelRecords($workspaceId: String!, $modelSlug: String!, $filter: JSON, $sort: String, $limit: Int, $offset: Int, $populate: [String!]) {\n publicModelRecords(workspaceId: $workspaceId, modelSlug: $modelSlug, filter: $filter, sort: $sort, limit: $limit, offset: $offset, populate: $populate) {\n items { id modelId data status createdAt updatedAt }\n total\n hasMore\n }\n}";
115
- interface CmssyFormField {
116
- id: string;
117
- name: string;
118
- fieldType: string;
119
- label: string | null;
120
- placeholder: string | null;
121
- helpText: string | null;
122
- defaultValue: unknown;
123
- options: unknown;
124
- validation: unknown;
125
- width: string | null;
126
- order: number | null;
127
- showIf: unknown;
128
- }
129
- interface CmssyFormSettings {
130
- actionType: string | null;
131
- submitButtonLabel: unknown;
132
- successMessage: unknown;
133
- errorMessage: unknown;
134
- redirectUrl: string | null;
135
- requireLogin: boolean | null;
136
- enableCaptcha: boolean | null;
137
- }
138
- interface CmssyFormDefinition {
139
- id: string;
140
- name: string;
141
- slug: string | null;
142
- description: string | null;
143
- fields: CmssyFormField[];
144
- settings: CmssyFormSettings | null;
145
- }
146
- interface CmssyFormSubmitResponse {
147
- success: boolean;
148
- message: string | null;
149
- submissionId: string | null;
150
- redirectUrl: string | null;
151
- accessToken: string | null;
152
- customer: unknown;
153
- }
154
- interface SubmitFormInput {
155
- data: Record<string, unknown>;
156
- website?: string;
157
- }
158
- declare const FORM_QUERY = "query PublicForm($formId: ID!) {\n publicForm(formId: $formId) {\n id\n name\n slug\n description\n fields {\n id name fieldType label placeholder helpText\n defaultValue width order showIf\n options { value label disabled }\n validation { required minLength maxLength minValue maxValue pattern customMessage }\n }\n settings {\n actionType submitButtonLabel successMessage errorMessage\n redirectUrl requireLogin enableCaptcha\n }\n }\n}";
159
- declare const SUBMIT_FORM_MUTATION = "mutation SubmitForm($formId: ID!, $input: SubmitFormInput!) {\n submitForm(formId: $formId, input: $input) {\n success message submissionId redirectUrl accessToken customer\n }\n}";
74
+ declare function collectFormIds(blocks: RawBlock[], locale: string, defaultLocale: string): string[];
75
+ declare function resolveForms(config: CmssyClientConfig, blocks: RawBlock[], locale: string, defaultLocale: string, options?: QueryScopedOptions): Promise<Record<string, CmssyFormDefinition>>;
160
76
 
161
77
  interface CmssyBlockProps {
162
78
  block: RawBlock;
@@ -175,4 +91,4 @@ interface UnknownBlockProps {
175
91
  }
176
92
  declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
177
93
 
178
- export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyBranding, type CmssyClient, CmssyClientConfig, type CmssyFormDefinition, type CmssyFormField, type CmssyFormSettings, type CmssyFormSubmitResponse, CmssyLayoutGroup, type CmssyModelDefinition, type CmssyModelRecord, CmssyPageData, type CmssyRecordList, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteConfig, EditorToAppMessage, FORM_QUERY, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, type PostTarget, type QueryScopedOptions, RawBlock, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, type SubmitFormInput, UnknownBlock, type UnknownBlockProps, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor };
94
+ export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, d as FetchLike, e as CmssyClientConfig, R as RawBlock, f as BlockMap, g as CmssyBlockContext } from './registry-suRGkEQs.js';
2
- export { a as BlockMeta, h as BlockRect, B as BlockSchema, i as BoundsMessage, j as ClickMessage, k as CmssyLocaleContext, l as FetchLikeResponse, m as FetchPageOptions, n as FieldType, P as PROTOCOL_VERSION, o as ParentReadyMessage, p as PatchMessage, q as RawLayoutBlock, r as ReadyMessage, S as SelectMessage, s as blocksToMeta, t as blocksToSchemas, u as buildBlockContext, v as buildBlockMap, w as defineBlock, x as fetchLayouts, y as fetchPage, z as isProtocolCompatible, D as normalizeSlug } from './registry-suRGkEQs.js';
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-BaFQ2k7r.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-BaFQ2k7r.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import 'react';
5
5
 
@@ -28,8 +28,10 @@ interface CmssyServerPageProps {
28
28
  defaultLocale?: string;
29
29
  /** All languages enabled on the workspace; exposed to blocks via context.locale.enabled. */
30
30
  enabledLocales?: string[];
31
+ /** Form definitions referenced by page blocks, exposed via context.forms. */
32
+ forms?: Record<string, CmssyFormDefinition>;
31
33
  }
32
- declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, }: CmssyServerPageProps): react_jsx_runtime.JSX.Element | null;
34
+ declare function CmssyServerPage({ page, blocks, locale, defaultLocale, enabledLocales, forms, }: CmssyServerPageProps): react_jsx_runtime.JSX.Element | null;
33
35
 
34
36
  interface CmssyServerLayoutProps {
35
37
  groups: CmssyLayoutGroup[];
@@ -69,94 +71,8 @@ interface CmssyClient {
69
71
  }
70
72
  declare function createCmssyClient(config: CmssyClientConfig): CmssyClient;
71
73
 
72
- interface CmssyBranding {
73
- brandName: string | null;
74
- logoUrl: string | null;
75
- faviconUrl: string | null;
76
- ogImageUrl: string | null;
77
- }
78
- interface CmssySiteConfig {
79
- id: string;
80
- workspaceId: string;
81
- siteName: unknown;
82
- defaultLanguage: string | null;
83
- enabledLanguages: string[];
84
- enabledFeatures: string[];
85
- notFoundPageId: string | null;
86
- previewUrl: string | null;
87
- branding: CmssyBranding | null;
88
- }
89
- 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}";
90
- interface CmssyModelDefinition {
91
- id: string;
92
- name: string;
93
- slug: string;
94
- description: string | null;
95
- icon: string | null;
96
- color: string | null;
97
- displayField: string | null;
98
- recordCount: number | null;
99
- }
100
- interface CmssyModelRecord {
101
- id: string;
102
- modelId: string;
103
- data: Record<string, unknown>;
104
- status: string | null;
105
- createdAt: string | null;
106
- updatedAt: string | null;
107
- }
108
- interface CmssyRecordList {
109
- items: CmssyModelRecord[];
110
- total: number;
111
- hasMore: boolean;
112
- }
113
- declare const MODEL_DEFINITIONS_QUERY = "query PublicModelDefinitions($workspaceId: String!) {\n publicModelDefinitions(workspaceId: $workspaceId) {\n id name slug description icon color displayField recordCount\n }\n}";
114
- declare const MODEL_RECORDS_QUERY = "query PublicModelRecords($workspaceId: String!, $modelSlug: String!, $filter: JSON, $sort: String, $limit: Int, $offset: Int, $populate: [String!]) {\n publicModelRecords(workspaceId: $workspaceId, modelSlug: $modelSlug, filter: $filter, sort: $sort, limit: $limit, offset: $offset, populate: $populate) {\n items { id modelId data status createdAt updatedAt }\n total\n hasMore\n }\n}";
115
- interface CmssyFormField {
116
- id: string;
117
- name: string;
118
- fieldType: string;
119
- label: string | null;
120
- placeholder: string | null;
121
- helpText: string | null;
122
- defaultValue: unknown;
123
- options: unknown;
124
- validation: unknown;
125
- width: string | null;
126
- order: number | null;
127
- showIf: unknown;
128
- }
129
- interface CmssyFormSettings {
130
- actionType: string | null;
131
- submitButtonLabel: unknown;
132
- successMessage: unknown;
133
- errorMessage: unknown;
134
- redirectUrl: string | null;
135
- requireLogin: boolean | null;
136
- enableCaptcha: boolean | null;
137
- }
138
- interface CmssyFormDefinition {
139
- id: string;
140
- name: string;
141
- slug: string | null;
142
- description: string | null;
143
- fields: CmssyFormField[];
144
- settings: CmssyFormSettings | null;
145
- }
146
- interface CmssyFormSubmitResponse {
147
- success: boolean;
148
- message: string | null;
149
- submissionId: string | null;
150
- redirectUrl: string | null;
151
- accessToken: string | null;
152
- customer: unknown;
153
- }
154
- interface SubmitFormInput {
155
- data: Record<string, unknown>;
156
- website?: string;
157
- }
158
- declare const FORM_QUERY = "query PublicForm($formId: ID!) {\n publicForm(formId: $formId) {\n id\n name\n slug\n description\n fields {\n id name fieldType label placeholder helpText\n defaultValue width order showIf\n options { value label disabled }\n validation { required minLength maxLength minValue maxValue pattern customMessage }\n }\n settings {\n actionType submitButtonLabel successMessage errorMessage\n redirectUrl requireLogin enableCaptcha\n }\n }\n}";
159
- declare const SUBMIT_FORM_MUTATION = "mutation SubmitForm($formId: ID!, $input: SubmitFormInput!) {\n submitForm(formId: $formId, input: $input) {\n success message submissionId redirectUrl accessToken customer\n }\n}";
74
+ declare function collectFormIds(blocks: RawBlock[], locale: string, defaultLocale: string): string[];
75
+ declare function resolveForms(config: CmssyClientConfig, blocks: RawBlock[], locale: string, defaultLocale: string, options?: QueryScopedOptions): Promise<Record<string, CmssyFormDefinition>>;
160
76
 
161
77
  interface CmssyBlockProps {
162
78
  block: RawBlock;
@@ -175,4 +91,4 @@ interface UnknownBlockProps {
175
91
  }
176
92
  declare function UnknownBlock({ type }: UnknownBlockProps): react_jsx_runtime.JSX.Element;
177
93
 
178
- export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyBranding, type CmssyClient, CmssyClientConfig, type CmssyFormDefinition, type CmssyFormField, type CmssyFormSettings, type CmssyFormSubmitResponse, CmssyLayoutGroup, type CmssyModelDefinition, type CmssyModelRecord, CmssyPageData, type CmssyRecordList, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, type CmssySiteConfig, EditorToAppMessage, FORM_QUERY, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, MODEL_DEFINITIONS_QUERY, MODEL_RECORDS_QUERY, type PostTarget, type QueryScopedOptions, RawBlock, SITE_CONFIG_QUERY, SUBMIT_FORM_MUTATION, type SubmitFormInput, UnknownBlock, type UnknownBlockProps, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor };
94
+ export { AppToEditorMessage, BlockDefinition, BlockMap, CmssyBlock, CmssyBlockContext, type CmssyBlockProps, type CmssyClient, CmssyClientConfig, CmssyFormDefinition, CmssyLayoutGroup, CmssyPageData, CmssyServerLayout, type CmssyServerLayoutProps, CmssyServerPage, type CmssyServerPageProps, EditorToAppMessage, FetchLike, type FieldControl, FieldDefinition, type GraphqlRequestOptions, type PostTarget, type QueryScopedOptions, RawBlock, UnknownBlock, type UnknownBlockProps, collectFormIds, createCmssyClient, fields, getBlockContentForLanguage, graphqlRequest, normalizeOrigin, parseEditorMessage, postToEditor, resolveForms };
package/dist/index.js CHANGED
@@ -59,14 +59,15 @@ function blocksToMeta(blocks, defaults = {}) {
59
59
  }
60
60
 
61
61
  // src/components/block-context.ts
62
- function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview) {
62
+ function buildBlockContext(locale, defaultLocale, enabledLocales, isPreview, forms) {
63
63
  return {
64
64
  locale: {
65
65
  current: locale,
66
66
  default: defaultLocale,
67
67
  enabled: enabledLocales && enabledLocales.length > 0 ? enabledLocales : Array.from(/* @__PURE__ */ new Set([defaultLocale, locale]))
68
68
  },
69
- isPreview: isPreview ?? false
69
+ isPreview: isPreview ?? false,
70
+ forms
70
71
  };
71
72
  }
72
73
 
@@ -126,11 +127,18 @@ function CmssyServerPage({
126
127
  blocks,
127
128
  locale = "en",
128
129
  defaultLocale = "en",
129
- enabledLocales
130
+ enabledLocales,
131
+ forms
130
132
  }) {
131
133
  if (!page) return null;
132
134
  const map = buildBlockMap(blocks);
133
- const context = buildBlockContext(locale, defaultLocale, enabledLocales);
135
+ const context = buildBlockContext(
136
+ locale,
137
+ defaultLocale,
138
+ enabledLocales,
139
+ false,
140
+ forms
141
+ );
134
142
  return /* @__PURE__ */ jsx(Fragment, { children: page.blocks.map(
135
143
  (block) => renderResolvedBlock(block, map, locale, defaultLocale, context)
136
144
  ) });
@@ -499,6 +507,44 @@ function createCmssyClient(config) {
499
507
  }
500
508
  };
501
509
  }
510
+
511
+ // src/data/resolve-forms.ts
512
+ function collectFormIds(blocks, locale, defaultLocale) {
513
+ const ids = /* @__PURE__ */ new Set();
514
+ for (const block of blocks) {
515
+ const content = getBlockContentForLanguage(
516
+ block.content,
517
+ locale,
518
+ defaultLocale
519
+ );
520
+ const formId = content.formId;
521
+ if (typeof formId === "string" && formId.trim()) ids.add(formId);
522
+ }
523
+ return [...ids];
524
+ }
525
+ async function resolveForms(config, blocks, locale, defaultLocale, options) {
526
+ const ids = collectFormIds(blocks, locale, defaultLocale);
527
+ if (ids.length === 0) return {};
528
+ const client = createCmssyClient(config);
529
+ const entries = await Promise.all(
530
+ ids.map(async (id) => {
531
+ try {
532
+ const data = await client.queryScoped(FORM_QUERY, { formId: id }, options);
533
+ return [id, data.publicForm];
534
+ } catch (err) {
535
+ if (typeof console !== "undefined") {
536
+ console.warn(`[cmssy] failed to resolve form ${id}`, err);
537
+ }
538
+ return [id, null];
539
+ }
540
+ })
541
+ );
542
+ const forms = {};
543
+ for (const [id, def] of entries) {
544
+ if (def) forms[id] = def;
545
+ }
546
+ return forms;
547
+ }
502
548
  function CmssyBlock({
503
549
  block,
504
550
  locale,
@@ -525,4 +571,4 @@ function CmssyBlock({
525
571
  );
526
572
  }
527
573
 
528
- 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, createCmssyClient, defineBlock, fetchLayouts, fetchPage, fields, getBlockContentForLanguage, graphqlRequest, isProtocolCompatible, normalizeOrigin, normalizeSlug, parseEditorMessage, postToEditor };
574
+ 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 };
@@ -44,6 +44,95 @@ declare function normalizeSlug(path: string | string[] | undefined): string;
44
44
  declare function fetchPage(config: CmssyClientConfig, path: string | string[] | undefined, options?: FetchPageOptions): Promise<CmssyPageData | null>;
45
45
  declare function fetchLayouts(config: CmssyClientConfig, path: string | string[] | undefined, options?: FetchPageOptions): Promise<CmssyLayoutGroup[]>;
46
46
 
47
+ interface CmssyBranding {
48
+ brandName: string | null;
49
+ logoUrl: string | null;
50
+ faviconUrl: string | null;
51
+ ogImageUrl: string | null;
52
+ }
53
+ interface CmssySiteConfig {
54
+ id: string;
55
+ workspaceId: string;
56
+ siteName: unknown;
57
+ defaultLanguage: string | null;
58
+ enabledLanguages: string[];
59
+ enabledFeatures: string[];
60
+ notFoundPageId: string | null;
61
+ previewUrl: string | null;
62
+ branding: CmssyBranding | null;
63
+ }
64
+ 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}";
65
+ interface CmssyModelDefinition {
66
+ id: string;
67
+ name: string;
68
+ slug: string;
69
+ description: string | null;
70
+ icon: string | null;
71
+ color: string | null;
72
+ displayField: string | null;
73
+ recordCount: number | null;
74
+ }
75
+ interface CmssyModelRecord {
76
+ id: string;
77
+ modelId: string;
78
+ data: Record<string, unknown>;
79
+ status: string | null;
80
+ createdAt: string | null;
81
+ updatedAt: string | null;
82
+ }
83
+ interface CmssyRecordList {
84
+ items: CmssyModelRecord[];
85
+ total: number;
86
+ hasMore: boolean;
87
+ }
88
+ declare const MODEL_DEFINITIONS_QUERY = "query PublicModelDefinitions($workspaceId: String!) {\n publicModelDefinitions(workspaceId: $workspaceId) {\n id name slug description icon color displayField recordCount\n }\n}";
89
+ declare const MODEL_RECORDS_QUERY = "query PublicModelRecords($workspaceId: String!, $modelSlug: String!, $filter: JSON, $sort: String, $limit: Int, $offset: Int, $populate: [String!]) {\n publicModelRecords(workspaceId: $workspaceId, modelSlug: $modelSlug, filter: $filter, sort: $sort, limit: $limit, offset: $offset, populate: $populate) {\n items { id modelId data status createdAt updatedAt }\n total\n hasMore\n }\n}";
90
+ interface CmssyFormField {
91
+ id: string;
92
+ name: string;
93
+ fieldType: string;
94
+ label: string | null;
95
+ placeholder: string | null;
96
+ helpText: string | null;
97
+ defaultValue: unknown;
98
+ options: unknown;
99
+ validation: unknown;
100
+ width: string | null;
101
+ order: number | null;
102
+ showIf: unknown;
103
+ }
104
+ interface CmssyFormSettings {
105
+ actionType: string | null;
106
+ submitButtonLabel: unknown;
107
+ successMessage: unknown;
108
+ errorMessage: unknown;
109
+ redirectUrl: string | null;
110
+ requireLogin: boolean | null;
111
+ enableCaptcha: boolean | null;
112
+ }
113
+ interface CmssyFormDefinition {
114
+ id: string;
115
+ name: string;
116
+ slug: string | null;
117
+ description: string | null;
118
+ fields: CmssyFormField[];
119
+ settings: CmssyFormSettings | null;
120
+ }
121
+ interface CmssyFormSubmitResponse {
122
+ success: boolean;
123
+ message: string | null;
124
+ submissionId: string | null;
125
+ redirectUrl: string | null;
126
+ accessToken: string | null;
127
+ customer: unknown;
128
+ }
129
+ interface SubmitFormInput {
130
+ data: Record<string, unknown>;
131
+ website?: string;
132
+ }
133
+ declare const FORM_QUERY = "query PublicForm($formId: ID!) {\n publicForm(formId: $formId) {\n id\n name\n slug\n description\n fields {\n id name fieldType label placeholder helpText\n defaultValue width order showIf\n options { value label disabled }\n validation { required minLength maxLength minValue maxValue pattern customMessage }\n }\n settings {\n actionType submitButtonLabel successMessage errorMessage\n redirectUrl requireLogin enableCaptcha\n }\n }\n}";
134
+ declare const SUBMIT_FORM_MUTATION = "mutation SubmitForm($formId: ID!, $input: SubmitFormInput!) {\n submitForm(formId: $formId, input: $input) {\n success message submissionId redirectUrl accessToken customer\n }\n}";
135
+
47
136
  interface CmssyLocaleContext {
48
137
  current: string;
49
138
  default: string;
@@ -52,8 +141,9 @@ interface CmssyLocaleContext {
52
141
  interface CmssyBlockContext {
53
142
  locale: CmssyLocaleContext;
54
143
  isPreview: boolean;
144
+ forms?: Record<string, CmssyFormDefinition>;
55
145
  }
56
- declare function buildBlockContext(locale: string, defaultLocale: string, enabledLocales?: string[], isPreview?: boolean): CmssyBlockContext;
146
+ declare function buildBlockContext(locale: string, defaultLocale: string, enabledLocales?: string[], isPreview?: boolean, forms?: Record<string, CmssyFormDefinition>): CmssyBlockContext;
57
147
 
58
148
  declare const PROTOCOL_VERSION = 1;
59
149
  type FieldType = "singleLine" | "multiLine" | "richText" | "numeric" | "date" | "media" | "link" | "select" | "multiselect" | "boolean" | "color" | "repeater";
@@ -200,4 +290,4 @@ declare function blocksToMeta(blocks: BlockDefinition[], defaults?: {
200
290
  category?: string;
201
291
  }): Record<string, BlockMeta>;
202
292
 
203
- export { type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, normalizeSlug as D, type EditorToAppMessage as E, type FieldDefinition as F, PROTOCOL_VERSION as P, type RawBlock as R, type SelectMessage as S, type BlockMeta as a, type BlockDefinition as b, type CmssyLayoutGroup as c, type FetchLike as d, type CmssyClientConfig as e, type BlockMap as f, type CmssyBlockContext as g, type BlockRect as h, type BoundsMessage as i, type ClickMessage as j, type CmssyLocaleContext as k, type FetchLikeResponse as l, type FetchPageOptions as m, type FieldType as n, type ParentReadyMessage as o, type PatchMessage as p, type RawLayoutBlock as q, type ReadyMessage as r, blocksToMeta as s, blocksToSchemas as t, buildBlockContext as u, buildBlockMap as v, defineBlock as w, fetchLayouts as x, fetchPage as y, isProtocolCompatible as z };
293
+ export { type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type PatchMessage as D, type EditorToAppMessage as E, type FieldDefinition as F, type RawLayoutBlock as G, type ReadyMessage as H, SUBMIT_FORM_MUTATION as I, type SelectMessage as J, type SubmitFormInput as K, blocksToMeta as L, MODEL_DEFINITIONS_QUERY as M, blocksToSchemas as N, buildBlockContext as O, PROTOCOL_VERSION as P, buildBlockMap as Q, type RawBlock as R, SITE_CONFIG_QUERY as S, defineBlock as T, fetchLayouts as U, fetchPage as V, isProtocolCompatible as W, normalizeSlug as X, type BlockMeta as a, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type FetchLike as e, type CmssyClientConfig as f, type BlockMap as g, type CmssyBlockContext as h, type BlockRect as i, type BoundsMessage as j, type ClickMessage as k, type CmssyBranding as l, type CmssyFormField as m, type CmssyFormSettings as n, type CmssyFormSubmitResponse as o, type CmssyLocaleContext as p, type CmssyModelDefinition as q, type CmssyModelRecord as r, type CmssyRecordList as s, type CmssySiteConfig as t, FORM_QUERY as u, type FetchLikeResponse as v, type FetchPageOptions as w, type FieldType as x, MODEL_RECORDS_QUERY as y, type ParentReadyMessage as z };
@@ -44,6 +44,95 @@ declare function normalizeSlug(path: string | string[] | undefined): string;
44
44
  declare function fetchPage(config: CmssyClientConfig, path: string | string[] | undefined, options?: FetchPageOptions): Promise<CmssyPageData | null>;
45
45
  declare function fetchLayouts(config: CmssyClientConfig, path: string | string[] | undefined, options?: FetchPageOptions): Promise<CmssyLayoutGroup[]>;
46
46
 
47
+ interface CmssyBranding {
48
+ brandName: string | null;
49
+ logoUrl: string | null;
50
+ faviconUrl: string | null;
51
+ ogImageUrl: string | null;
52
+ }
53
+ interface CmssySiteConfig {
54
+ id: string;
55
+ workspaceId: string;
56
+ siteName: unknown;
57
+ defaultLanguage: string | null;
58
+ enabledLanguages: string[];
59
+ enabledFeatures: string[];
60
+ notFoundPageId: string | null;
61
+ previewUrl: string | null;
62
+ branding: CmssyBranding | null;
63
+ }
64
+ 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}";
65
+ interface CmssyModelDefinition {
66
+ id: string;
67
+ name: string;
68
+ slug: string;
69
+ description: string | null;
70
+ icon: string | null;
71
+ color: string | null;
72
+ displayField: string | null;
73
+ recordCount: number | null;
74
+ }
75
+ interface CmssyModelRecord {
76
+ id: string;
77
+ modelId: string;
78
+ data: Record<string, unknown>;
79
+ status: string | null;
80
+ createdAt: string | null;
81
+ updatedAt: string | null;
82
+ }
83
+ interface CmssyRecordList {
84
+ items: CmssyModelRecord[];
85
+ total: number;
86
+ hasMore: boolean;
87
+ }
88
+ declare const MODEL_DEFINITIONS_QUERY = "query PublicModelDefinitions($workspaceId: String!) {\n publicModelDefinitions(workspaceId: $workspaceId) {\n id name slug description icon color displayField recordCount\n }\n}";
89
+ declare const MODEL_RECORDS_QUERY = "query PublicModelRecords($workspaceId: String!, $modelSlug: String!, $filter: JSON, $sort: String, $limit: Int, $offset: Int, $populate: [String!]) {\n publicModelRecords(workspaceId: $workspaceId, modelSlug: $modelSlug, filter: $filter, sort: $sort, limit: $limit, offset: $offset, populate: $populate) {\n items { id modelId data status createdAt updatedAt }\n total\n hasMore\n }\n}";
90
+ interface CmssyFormField {
91
+ id: string;
92
+ name: string;
93
+ fieldType: string;
94
+ label: string | null;
95
+ placeholder: string | null;
96
+ helpText: string | null;
97
+ defaultValue: unknown;
98
+ options: unknown;
99
+ validation: unknown;
100
+ width: string | null;
101
+ order: number | null;
102
+ showIf: unknown;
103
+ }
104
+ interface CmssyFormSettings {
105
+ actionType: string | null;
106
+ submitButtonLabel: unknown;
107
+ successMessage: unknown;
108
+ errorMessage: unknown;
109
+ redirectUrl: string | null;
110
+ requireLogin: boolean | null;
111
+ enableCaptcha: boolean | null;
112
+ }
113
+ interface CmssyFormDefinition {
114
+ id: string;
115
+ name: string;
116
+ slug: string | null;
117
+ description: string | null;
118
+ fields: CmssyFormField[];
119
+ settings: CmssyFormSettings | null;
120
+ }
121
+ interface CmssyFormSubmitResponse {
122
+ success: boolean;
123
+ message: string | null;
124
+ submissionId: string | null;
125
+ redirectUrl: string | null;
126
+ accessToken: string | null;
127
+ customer: unknown;
128
+ }
129
+ interface SubmitFormInput {
130
+ data: Record<string, unknown>;
131
+ website?: string;
132
+ }
133
+ declare const FORM_QUERY = "query PublicForm($formId: ID!) {\n publicForm(formId: $formId) {\n id\n name\n slug\n description\n fields {\n id name fieldType label placeholder helpText\n defaultValue width order showIf\n options { value label disabled }\n validation { required minLength maxLength minValue maxValue pattern customMessage }\n }\n settings {\n actionType submitButtonLabel successMessage errorMessage\n redirectUrl requireLogin enableCaptcha\n }\n }\n}";
134
+ declare const SUBMIT_FORM_MUTATION = "mutation SubmitForm($formId: ID!, $input: SubmitFormInput!) {\n submitForm(formId: $formId, input: $input) {\n success message submissionId redirectUrl accessToken customer\n }\n}";
135
+
47
136
  interface CmssyLocaleContext {
48
137
  current: string;
49
138
  default: string;
@@ -52,8 +141,9 @@ interface CmssyLocaleContext {
52
141
  interface CmssyBlockContext {
53
142
  locale: CmssyLocaleContext;
54
143
  isPreview: boolean;
144
+ forms?: Record<string, CmssyFormDefinition>;
55
145
  }
56
- declare function buildBlockContext(locale: string, defaultLocale: string, enabledLocales?: string[], isPreview?: boolean): CmssyBlockContext;
146
+ declare function buildBlockContext(locale: string, defaultLocale: string, enabledLocales?: string[], isPreview?: boolean, forms?: Record<string, CmssyFormDefinition>): CmssyBlockContext;
57
147
 
58
148
  declare const PROTOCOL_VERSION = 1;
59
149
  type FieldType = "singleLine" | "multiLine" | "richText" | "numeric" | "date" | "media" | "link" | "select" | "multiselect" | "boolean" | "color" | "repeater";
@@ -200,4 +290,4 @@ declare function blocksToMeta(blocks: BlockDefinition[], defaults?: {
200
290
  category?: string;
201
291
  }): Record<string, BlockMeta>;
202
292
 
203
- export { type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, normalizeSlug as D, type EditorToAppMessage as E, type FieldDefinition as F, PROTOCOL_VERSION as P, type RawBlock as R, type SelectMessage as S, type BlockMeta as a, type BlockDefinition as b, type CmssyLayoutGroup as c, type FetchLike as d, type CmssyClientConfig as e, type BlockMap as f, type CmssyBlockContext as g, type BlockRect as h, type BoundsMessage as i, type ClickMessage as j, type CmssyLocaleContext as k, type FetchLikeResponse as l, type FetchPageOptions as m, type FieldType as n, type ParentReadyMessage as o, type PatchMessage as p, type RawLayoutBlock as q, type ReadyMessage as r, blocksToMeta as s, blocksToSchemas as t, buildBlockContext as u, buildBlockMap as v, defineBlock as w, fetchLayouts as x, fetchPage as y, isProtocolCompatible as z };
293
+ export { type AppToEditorMessage as A, type BlockSchema as B, type CmssyPageData as C, type PatchMessage as D, type EditorToAppMessage as E, type FieldDefinition as F, type RawLayoutBlock as G, type ReadyMessage as H, SUBMIT_FORM_MUTATION as I, type SelectMessage as J, type SubmitFormInput as K, blocksToMeta as L, MODEL_DEFINITIONS_QUERY as M, blocksToSchemas as N, buildBlockContext as O, PROTOCOL_VERSION as P, buildBlockMap as Q, type RawBlock as R, SITE_CONFIG_QUERY as S, defineBlock as T, fetchLayouts as U, fetchPage as V, isProtocolCompatible as W, normalizeSlug as X, type BlockMeta as a, type BlockDefinition as b, type CmssyFormDefinition as c, type CmssyLayoutGroup as d, type FetchLike as e, type CmssyClientConfig as f, type BlockMap as g, type CmssyBlockContext as h, type BlockRect as i, type BoundsMessage as j, type ClickMessage as k, type CmssyBranding as l, type CmssyFormField as m, type CmssyFormSettings as n, type CmssyFormSubmitResponse as o, type CmssyLocaleContext as p, type CmssyModelDefinition as q, type CmssyModelRecord as r, type CmssyRecordList as s, type CmssySiteConfig as t, FORM_QUERY as u, type FetchLikeResponse as v, type FetchPageOptions as w, type FieldType as x, MODEL_RECORDS_QUERY as y, type ParentReadyMessage as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",