@cmssy/react 16.8.0 → 16.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,6 +95,21 @@ export const CmssyEditor = (props) => (
95
95
  The editor talks to the cmssy admin over the `cmssy:*` bridge protocol for live
96
96
  preview.
97
97
 
98
+ ## Versioning: this package, not the API
99
+
100
+ **Pinning this package does not pin the API it talks to.** The package version
101
+ covers this client - its exports and their behaviour, normal semver. The cmssy
102
+ delivery API is a hosted service whose GraphQL schema can change on any deploy,
103
+ without a release here.
104
+
105
+ There is no dated API version to pin; the delivery endpoint has no version
106
+ segment. What protects you today is that a breaking schema change cannot merge
107
+ silently - it is caught by a gate that validates the SDK's own operations, and
108
+ shipping one anyway takes a recorded approval - and that fields we intend to
109
+ remove are marked `@deprecated` first. There is no guaranteed deprecation window
110
+ and no minimum notice period. Details in
111
+ [`@cmssy/core`](https://www.npmjs.com/package/@cmssy/core).
112
+
98
113
  ## License
99
114
 
100
115
  MIT
package/dist/index.cjs CHANGED
@@ -734,6 +734,44 @@ async function handleBlockDataRequest(body, options) {
734
734
  headers: { "cache-control": "no-store" }
735
735
  });
736
736
  }
737
+ function pageOf(body) {
738
+ if (typeof body !== "object" || body === null) return "";
739
+ const page = body.page;
740
+ if (typeof page !== "object" || page === null) return "";
741
+ const slug = page.slug;
742
+ return typeof slug === "string" ? slug : "";
743
+ }
744
+ function createBlockDataHandler(config, blocks, options = {}) {
745
+ return async function handle(request) {
746
+ if (!config.draftSecret) {
747
+ return new Response(
748
+ "cmssy: the block data route needs config.draftSecret to verify the editor",
749
+ { status: 500 }
750
+ );
751
+ }
752
+ let body;
753
+ try {
754
+ body = await request.json();
755
+ } catch {
756
+ return Response.json(
757
+ { message: "cmssy: body is not JSON" },
758
+ { status: 400 }
759
+ );
760
+ }
761
+ const authorized = await core.verifyCmssyEditToken(
762
+ request.headers.get(core.CMSSY_EDIT_TOKEN_HEADER),
763
+ config.draftSecret,
764
+ { page: pageOf(body) }
765
+ );
766
+ if (!authorized) {
767
+ return new Response(
768
+ "cmssy: block data needs the edit token the editor page was rendered with",
769
+ { status: 403 }
770
+ );
771
+ }
772
+ return handleBlockDataRequest(body, { blocks, config, ...options });
773
+ };
774
+ }
737
775
 
738
776
  Object.defineProperty(exports, "CmssyRequestError", {
739
777
  enumerable: true,
@@ -796,6 +834,7 @@ exports.CmssyServerLayout = CmssyServerLayout;
796
834
  exports.CmssyServerPage = CmssyServerPage;
797
835
  exports.UnknownBlock = UnknownBlock;
798
836
  exports.buildBlockMap = buildBlockMap;
837
+ exports.createBlockDataHandler = createBlockDataHandler;
799
838
  exports.defineBlock = defineBlock;
800
839
  exports.handleBlockDataRequest = handleBlockDataRequest;
801
840
  exports.parseBlockDataRequest = parseBlockDataRequest;
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ export { FieldCondition, FieldConditionGroup, FieldConditionLogic } from '@cmssy
7
7
  export { buildBlockContext } from '@cmssy/core/internal';
8
8
  import * as react_jsx_runtime from 'react/jsx-runtime';
9
9
  import { ReactElement, ComponentType } from 'react';
10
- export { CmssyBlockDataRequest, CmssyBlockDataRequestBlock, CmssyBlockDataRequestPage, CmssyBlockDataResult, ResolveBlockDataRequestOptions, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest } from './internal-server.cjs';
10
+ export { CmssyBlockDataHandlerOptions, CmssyBlockDataRequest, CmssyBlockDataRequestBlock, CmssyBlockDataRequestPage, CmssyBlockDataResult, ResolveBlockDataRequestOptions, createBlockDataHandler, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest } from './internal-server.cjs';
11
11
 
12
12
  interface CmssyServerPageProps {
13
13
  page: CmssyPageData | null;
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { FieldCondition, FieldConditionGroup, FieldConditionLogic } from '@cmssy
7
7
  export { buildBlockContext } from '@cmssy/core/internal';
8
8
  import * as react_jsx_runtime from 'react/jsx-runtime';
9
9
  import { ReactElement, ComponentType } from 'react';
10
- export { CmssyBlockDataRequest, CmssyBlockDataRequestBlock, CmssyBlockDataRequestPage, CmssyBlockDataResult, ResolveBlockDataRequestOptions, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest } from './internal-server.js';
10
+ export { CmssyBlockDataHandlerOptions, CmssyBlockDataRequest, CmssyBlockDataRequestBlock, CmssyBlockDataRequestPage, CmssyBlockDataResult, ResolveBlockDataRequestOptions, createBlockDataHandler, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest } from './internal-server.js';
11
11
 
12
12
  interface CmssyServerPageProps {
13
13
  page: CmssyPageData | null;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { blocksToSchemas, resolveEditorOrigin } from '@cmssy/core';
1
+ import { blocksToSchemas, resolveEditorOrigin, verifyCmssyEditToken, CMSSY_EDIT_TOKEN_HEADER } from '@cmssy/core';
2
2
  export { CmssyRequestError, PROTOCOL_VERSION, createCmssyClient, defineCmssyLayout, fields, graphqlRequest, isProtocolCompatible, mediaAlt, mediaUrl, mediaUrls, normalizeOrigin, parseEditorMessage, postToEditor } from '@cmssy/core';
3
3
  import { buildBlockContext, fetchLayouts, normalizeBlockContent, asBucket, resolveSiteLocales as resolveSiteLocales$1, getBlockContentForLanguage, resolveRelationContent } from '@cmssy/core/internal';
4
4
  export { buildBlockContext } from '@cmssy/core/internal';
@@ -734,5 +734,43 @@ async function handleBlockDataRequest(body, options) {
734
734
  headers: { "cache-control": "no-store" }
735
735
  });
736
736
  }
737
+ function pageOf(body) {
738
+ if (typeof body !== "object" || body === null) return "";
739
+ const page = body.page;
740
+ if (typeof page !== "object" || page === null) return "";
741
+ const slug = page.slug;
742
+ return typeof slug === "string" ? slug : "";
743
+ }
744
+ function createBlockDataHandler(config, blocks, options = {}) {
745
+ return async function handle(request) {
746
+ if (!config.draftSecret) {
747
+ return new Response(
748
+ "cmssy: the block data route needs config.draftSecret to verify the editor",
749
+ { status: 500 }
750
+ );
751
+ }
752
+ let body;
753
+ try {
754
+ body = await request.json();
755
+ } catch {
756
+ return Response.json(
757
+ { message: "cmssy: body is not JSON" },
758
+ { status: 400 }
759
+ );
760
+ }
761
+ const authorized = await verifyCmssyEditToken(
762
+ request.headers.get(CMSSY_EDIT_TOKEN_HEADER),
763
+ config.draftSecret,
764
+ { page: pageOf(body) }
765
+ );
766
+ if (!authorized) {
767
+ return new Response(
768
+ "cmssy: block data needs the edit token the editor page was rendered with",
769
+ { status: 403 }
770
+ );
771
+ }
772
+ return handleBlockDataRequest(body, { blocks, config, ...options });
773
+ };
774
+ }
737
775
 
738
- export { CmssyBlock, CmssyServerLayout, CmssyServerPage, UnknownBlock, buildBlockMap, defineBlock, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest, resolveCmssyLayout, resolveCmssyLayoutSlot, resolveEditorBlockData, resolveEditorLayoutBlockData };
776
+ export { CmssyBlock, CmssyServerLayout, CmssyServerPage, UnknownBlock, buildBlockMap, createBlockDataHandler, defineBlock, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest, resolveCmssyLayout, resolveCmssyLayoutSlot, resolveEditorBlockData, resolveEditorLayoutBlockData };
@@ -264,11 +264,50 @@ async function handleBlockDataRequest(body, options) {
264
264
  headers: { "cache-control": "no-store" }
265
265
  });
266
266
  }
267
+ function pageOf(body) {
268
+ if (typeof body !== "object" || body === null) return "";
269
+ const page = body.page;
270
+ if (typeof page !== "object" || page === null) return "";
271
+ const slug = page.slug;
272
+ return typeof slug === "string" ? slug : "";
273
+ }
274
+ function createBlockDataHandler(config, blocks, options = {}) {
275
+ return async function handle(request) {
276
+ if (!config.draftSecret) {
277
+ return new Response(
278
+ "cmssy: the block data route needs config.draftSecret to verify the editor",
279
+ { status: 500 }
280
+ );
281
+ }
282
+ let body;
283
+ try {
284
+ body = await request.json();
285
+ } catch {
286
+ return Response.json(
287
+ { message: "cmssy: body is not JSON" },
288
+ { status: 400 }
289
+ );
290
+ }
291
+ const authorized = await core.verifyCmssyEditToken(
292
+ request.headers.get(core.CMSSY_EDIT_TOKEN_HEADER),
293
+ config.draftSecret,
294
+ { page: pageOf(body) }
295
+ );
296
+ if (!authorized) {
297
+ return new Response(
298
+ "cmssy: block data needs the edit token the editor page was rendered with",
299
+ { status: 403 }
300
+ );
301
+ }
302
+ return handleBlockDataRequest(body, { blocks, config, ...options });
303
+ };
304
+ }
267
305
 
268
306
  Object.defineProperty(exports, "blocksToSchemas", {
269
307
  enumerable: true,
270
308
  get: function () { return core.blocksToSchemas; }
271
309
  });
310
+ exports.createBlockDataHandler = createBlockDataHandler;
272
311
  exports.handleBlockDataRequest = handleBlockDataRequest;
273
312
  exports.parseBlockDataRequest = parseBlockDataRequest;
274
313
  exports.resolveBlockData = resolveBlockData;
@@ -42,4 +42,13 @@ declare function parseBlockDataRequest(body: unknown): CmssyBlockDataRequest;
42
42
  declare function resolveBlockDataRequest(request: CmssyBlockDataRequest, options: ResolveBlockDataRequestOptions): Promise<CmssyBlockDataResult>;
43
43
  declare function handleBlockDataRequest(body: unknown, options: ResolveBlockDataRequestOptions): Promise<Response>;
44
44
 
45
- export { type CmssyBlockDataRequest, type CmssyBlockDataRequestBlock, type CmssyBlockDataRequestPage, type CmssyBlockDataResult, type ResolveBlockDataRequestOptions, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest };
45
+ interface CmssyBlockDataHandlerOptions {
46
+ forms?: Record<string, CmssyFormDefinition>;
47
+ appContext?: Record<string, unknown>;
48
+ workspaceId?: string;
49
+ }
50
+ declare function createBlockDataHandler(config: CmssyClientConfig & {
51
+ draftSecret?: string;
52
+ }, blocks: BlockDefinition[], options?: CmssyBlockDataHandlerOptions): (request: Request) => Promise<Response>;
53
+
54
+ export { type CmssyBlockDataHandlerOptions, type CmssyBlockDataRequest, type CmssyBlockDataRequestBlock, type CmssyBlockDataRequestPage, type CmssyBlockDataResult, type ResolveBlockDataRequestOptions, createBlockDataHandler, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest };
@@ -42,4 +42,13 @@ declare function parseBlockDataRequest(body: unknown): CmssyBlockDataRequest;
42
42
  declare function resolveBlockDataRequest(request: CmssyBlockDataRequest, options: ResolveBlockDataRequestOptions): Promise<CmssyBlockDataResult>;
43
43
  declare function handleBlockDataRequest(body: unknown, options: ResolveBlockDataRequestOptions): Promise<Response>;
44
44
 
45
- export { type CmssyBlockDataRequest, type CmssyBlockDataRequestBlock, type CmssyBlockDataRequestPage, type CmssyBlockDataResult, type ResolveBlockDataRequestOptions, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest };
45
+ interface CmssyBlockDataHandlerOptions {
46
+ forms?: Record<string, CmssyFormDefinition>;
47
+ appContext?: Record<string, unknown>;
48
+ workspaceId?: string;
49
+ }
50
+ declare function createBlockDataHandler(config: CmssyClientConfig & {
51
+ draftSecret?: string;
52
+ }, blocks: BlockDefinition[], options?: CmssyBlockDataHandlerOptions): (request: Request) => Promise<Response>;
53
+
54
+ export { type CmssyBlockDataHandlerOptions, type CmssyBlockDataRequest, type CmssyBlockDataRequestBlock, type CmssyBlockDataRequestPage, type CmssyBlockDataResult, type ResolveBlockDataRequestOptions, createBlockDataHandler, handleBlockDataRequest, parseBlockDataRequest, resolveBlockDataRequest };
@@ -1,5 +1,5 @@
1
1
  import { buildBlockContext, getBlockContentForLanguage, resolveRelationContent, normalizeBlockContent } from '@cmssy/core/internal';
2
- import { blocksToSchemas } from '@cmssy/core';
2
+ import { blocksToSchemas, verifyCmssyEditToken, CMSSY_EDIT_TOKEN_HEADER } from '@cmssy/core';
3
3
  export { blocksToSchemas } from '@cmssy/core';
4
4
 
5
5
  // src/components/resolve-block-data.ts
@@ -263,5 +263,43 @@ async function handleBlockDataRequest(body, options) {
263
263
  headers: { "cache-control": "no-store" }
264
264
  });
265
265
  }
266
+ function pageOf(body) {
267
+ if (typeof body !== "object" || body === null) return "";
268
+ const page = body.page;
269
+ if (typeof page !== "object" || page === null) return "";
270
+ const slug = page.slug;
271
+ return typeof slug === "string" ? slug : "";
272
+ }
273
+ function createBlockDataHandler(config, blocks, options = {}) {
274
+ return async function handle(request) {
275
+ if (!config.draftSecret) {
276
+ return new Response(
277
+ "cmssy: the block data route needs config.draftSecret to verify the editor",
278
+ { status: 500 }
279
+ );
280
+ }
281
+ let body;
282
+ try {
283
+ body = await request.json();
284
+ } catch {
285
+ return Response.json(
286
+ { message: "cmssy: body is not JSON" },
287
+ { status: 400 }
288
+ );
289
+ }
290
+ const authorized = await verifyCmssyEditToken(
291
+ request.headers.get(CMSSY_EDIT_TOKEN_HEADER),
292
+ config.draftSecret,
293
+ { page: pageOf(body) }
294
+ );
295
+ if (!authorized) {
296
+ return new Response(
297
+ "cmssy: block data needs the edit token the editor page was rendered with",
298
+ { status: 403 }
299
+ );
300
+ }
301
+ return handleBlockDataRequest(body, { blocks, config, ...options });
302
+ };
303
+ }
266
304
 
267
- export { handleBlockDataRequest, parseBlockDataRequest, resolveBlockData, resolveBlockDataRequest, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
305
+ export { createBlockDataHandler, handleBlockDataRequest, parseBlockDataRequest, resolveBlockData, resolveBlockDataRequest, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "16.8.0",
3
+ "version": "16.9.1",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -97,7 +97,7 @@
97
97
  },
98
98
  "dependencies": {
99
99
  "@cmssy/types": "0.49.0",
100
- "@cmssy/core": "16.8.0"
100
+ "@cmssy/core": "16.9.1"
101
101
  },
102
102
  "scripts": {
103
103
  "build": "tsup",