@cmssy/next 10.10.0 → 11.1.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/server.cjs CHANGED
@@ -9,7 +9,6 @@ var internalServer = require('@cmssy/react/internal-server');
9
9
  var internal = require('@cmssy/core/internal');
10
10
  var core = require('@cmssy/core');
11
11
  var jsxRuntime = require('react/jsx-runtime');
12
- var locale = require('@cmssy/core/internal/locale');
13
12
 
14
13
  // src/server.ts
15
14
  function hasEditFlag(value) {
@@ -255,18 +254,21 @@ async function CmssyLayoutSlot({
255
254
  blocks,
256
255
  position,
257
256
  path,
257
+ locale: explicitLocale,
258
+ editMode,
258
259
  page = "/",
259
260
  editable: Editable,
260
261
  appContext
261
262
  }) {
262
- const editMode = await isCmssyEditMode();
263
- const [groups, siteLocales] = await Promise.all([
264
- internal.fetchLayouts(config, page, {
265
- previewSecret: editMode ? config.draftSecret : void 0
266
- }),
267
- locale.resolveSiteLocales(config)
268
- ]);
269
- const locale$1 = path ? locale.splitLocaleFromPath(path, siteLocales).locale : await localeFromHeader(siteLocales.defaultLocale);
263
+ const resolved = await react.resolveCmssyLayoutSlot(config, {
264
+ position,
265
+ blocks,
266
+ editMode,
267
+ page,
268
+ appContext,
269
+ ...explicitLocale !== void 0 ? { locale: explicitLocale } : { path: path ?? [] }
270
+ });
271
+ const { groups, locale, defaultLocale, enabledLocales } = resolved;
270
272
  if (!editMode) {
271
273
  return /* @__PURE__ */ jsxRuntime.jsx(
272
274
  react.CmssyServerLayout,
@@ -274,45 +276,30 @@ async function CmssyLayoutSlot({
274
276
  groups,
275
277
  blocks,
276
278
  position,
277
- locale: locale$1,
278
- defaultLocale: siteLocales.defaultLocale,
279
- enabledLocales: siteLocales.locales,
279
+ locale,
280
+ defaultLocale,
281
+ enabledLocales,
280
282
  config,
281
283
  appContext
282
284
  }
283
285
  );
284
286
  }
285
- const origin = core.resolveEditorOrigin(config.editorOrigin);
286
- const editorData = await react.resolveEditorLayoutBlockData({
287
- groups,
288
- blocks,
289
- position,
290
- locale: locale$1,
291
- defaultLocale: siteLocales.defaultLocale,
292
- enabledLocales: siteLocales.locales,
293
- isPreview: true,
294
- config,
295
- appContext
296
- });
287
+ const origin = resolved.editorOrigin;
297
288
  return /* @__PURE__ */ jsxRuntime.jsx(
298
289
  Editable,
299
290
  {
300
291
  groups,
301
292
  position,
302
- locale: locale$1,
303
- defaultLocale: siteLocales.defaultLocale,
304
- enabledLocales: siteLocales.locales,
293
+ locale,
294
+ defaultLocale,
295
+ enabledLocales,
305
296
  edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
306
- data: editorData.data,
307
- resolvedContent: editorData.content,
297
+ data: resolved.data,
298
+ resolvedContent: resolved.resolvedContent,
308
299
  appContext
309
300
  }
310
301
  );
311
302
  }
312
- async function localeFromHeader(defaultLocale) {
313
- const { headers: headers3 } = await import('next/headers');
314
- return (await headers3()).get(locale.CMSSY_LOCALE_HEADER) || defaultLocale;
315
- }
316
303
 
317
304
  exports.CmssyLayoutSlot = CmssyLayoutSlot;
318
305
  exports.createCmssyEditPage = createCmssyEditPage;
package/dist/server.d.cts CHANGED
@@ -12,7 +12,7 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
12
12
 
13
13
  declare function isCmssyEditMode(): Promise<boolean>;
14
14
 
15
- interface CmssyLayoutSlotProps {
15
+ interface CmssyLayoutSlotBaseProps {
16
16
  config: CmssyConfig;
17
17
  blocks: BlockDefinition[];
18
18
  /**
@@ -22,16 +22,15 @@ interface CmssyLayoutSlotProps {
22
22
  */
23
23
  position: LayoutPosition;
24
24
  /**
25
- * The catch-all segments of the route rendering this slot, **as routed**.
26
- * The language prefix in them IS the language, and reading it here keeps the
27
- * route statically renderable.
25
+ * Whether to render through the edit bridge. A parameter rather than a
26
+ * lookup: every way of asking the request - `headers()`, `draftMode()` - is a
27
+ * dynamic API, and one read makes the whole route uncacheable. The route
28
+ * segment already knows the answer, so it passes it.
28
29
  *
29
- * Omit it only where there are no params to read - a root layout - and the
30
- * language falls back to the header the middleware set, which means calling
31
- * `headers()` and giving up static rendering for the whole route. The version
32
- * of this component removed in 10.0 had no choice about that; this one does.
30
+ * Required on purpose. A slot that guessed `false` in an edit route would
31
+ * wrap draft content in published chrome, and nothing would report it.
33
32
  */
34
- path?: string[];
33
+ editMode: boolean;
35
34
  /** The page whose layout to render. Defaults to the site-wide header/footer. */
36
35
  page?: string;
37
36
  /**
@@ -58,6 +57,24 @@ interface CmssyLayoutSlotProps {
58
57
  /** Forwarded untouched to every block as `context.app`. */
59
58
  appContext?: Record<string, unknown>;
60
59
  }
60
+ /**
61
+ * Where the language comes from - one of two, never neither.
62
+ *
63
+ * `path` is the catch-all segments **as routed**: the language prefix in them
64
+ * IS the language, and reading it costs the route nothing. A caller with no
65
+ * params (a root layout) has to resolve the language itself and pass `locale`;
66
+ * there is deliberately no fallback to the request header, because a static
67
+ * route never sees the header the proxy set and would render the wrong
68
+ * language while looking like it worked.
69
+ */
70
+ type CmssyLayoutSlotLocaleSource = {
71
+ path: string[];
72
+ locale?: never;
73
+ } | {
74
+ locale: string;
75
+ path?: never;
76
+ };
77
+ type CmssyLayoutSlotProps = CmssyLayoutSlotBaseProps & CmssyLayoutSlotLocaleSource;
61
78
  /**
62
79
  * The site-wide header and footer, which are layout **blocks** rather than
63
80
  * markup the app owns. Rendered the way each mode needs them:
@@ -72,6 +89,6 @@ interface CmssyLayoutSlotProps {
72
89
  * app that wrote this by hand between 10.0 and 10.9 got at least one of the
73
90
  * three wrong, which is why it is back.
74
91
  */
75
- declare function CmssyLayoutSlot({ config, blocks, position, path, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
92
+ declare function CmssyLayoutSlot({ config, blocks, position, path, locale: explicitLocale, editMode, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
76
93
 
77
94
  export { type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, createDraftRoute, isCmssyEditMode };
package/dist/server.d.ts CHANGED
@@ -12,7 +12,7 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
12
12
 
13
13
  declare function isCmssyEditMode(): Promise<boolean>;
14
14
 
15
- interface CmssyLayoutSlotProps {
15
+ interface CmssyLayoutSlotBaseProps {
16
16
  config: CmssyConfig;
17
17
  blocks: BlockDefinition[];
18
18
  /**
@@ -22,16 +22,15 @@ interface CmssyLayoutSlotProps {
22
22
  */
23
23
  position: LayoutPosition;
24
24
  /**
25
- * The catch-all segments of the route rendering this slot, **as routed**.
26
- * The language prefix in them IS the language, and reading it here keeps the
27
- * route statically renderable.
25
+ * Whether to render through the edit bridge. A parameter rather than a
26
+ * lookup: every way of asking the request - `headers()`, `draftMode()` - is a
27
+ * dynamic API, and one read makes the whole route uncacheable. The route
28
+ * segment already knows the answer, so it passes it.
28
29
  *
29
- * Omit it only where there are no params to read - a root layout - and the
30
- * language falls back to the header the middleware set, which means calling
31
- * `headers()` and giving up static rendering for the whole route. The version
32
- * of this component removed in 10.0 had no choice about that; this one does.
30
+ * Required on purpose. A slot that guessed `false` in an edit route would
31
+ * wrap draft content in published chrome, and nothing would report it.
33
32
  */
34
- path?: string[];
33
+ editMode: boolean;
35
34
  /** The page whose layout to render. Defaults to the site-wide header/footer. */
36
35
  page?: string;
37
36
  /**
@@ -58,6 +57,24 @@ interface CmssyLayoutSlotProps {
58
57
  /** Forwarded untouched to every block as `context.app`. */
59
58
  appContext?: Record<string, unknown>;
60
59
  }
60
+ /**
61
+ * Where the language comes from - one of two, never neither.
62
+ *
63
+ * `path` is the catch-all segments **as routed**: the language prefix in them
64
+ * IS the language, and reading it costs the route nothing. A caller with no
65
+ * params (a root layout) has to resolve the language itself and pass `locale`;
66
+ * there is deliberately no fallback to the request header, because a static
67
+ * route never sees the header the proxy set and would render the wrong
68
+ * language while looking like it worked.
69
+ */
70
+ type CmssyLayoutSlotLocaleSource = {
71
+ path: string[];
72
+ locale?: never;
73
+ } | {
74
+ locale: string;
75
+ path?: never;
76
+ };
77
+ type CmssyLayoutSlotProps = CmssyLayoutSlotBaseProps & CmssyLayoutSlotLocaleSource;
61
78
  /**
62
79
  * The site-wide header and footer, which are layout **blocks** rather than
63
80
  * markup the app owns. Rendered the way each mode needs them:
@@ -72,6 +89,6 @@ interface CmssyLayoutSlotProps {
72
89
  * app that wrote this by hand between 10.0 and 10.9 got at least one of the
73
90
  * three wrong, which is why it is back.
74
91
  */
75
- declare function CmssyLayoutSlot({ config, blocks, position, path, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
92
+ declare function CmssyLayoutSlot({ config, blocks, position, path, locale: explicitLocale, editMode, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
76
93
 
77
94
  export { type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, createDraftRoute, isCmssyEditMode };
package/dist/server.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import 'server-only';
2
2
  import { draftMode, headers } from 'next/headers';
3
3
  import { notFound, redirect } from 'next/navigation';
4
- import { createCmssyClient, CmssyServerPage, CmssyServerLayout, resolveEditorLayoutBlockData } from '@cmssy/react';
4
+ import { createCmssyClient, CmssyServerPage, resolveCmssyLayoutSlot, CmssyServerLayout } from '@cmssy/react';
5
5
  import { CmssyLocaleProvider } from '@cmssy/react/internal';
6
6
  import { resolveEditorBlockData } from '@cmssy/react/internal-server';
7
- import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, fetchPage, resolveForms, toCspOrigin, cmssySecretsMatch, fetchLayouts } from '@cmssy/core/internal';
7
+ import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, fetchPage, resolveForms, toCspOrigin, cmssySecretsMatch } from '@cmssy/core/internal';
8
8
  import { CMSSY_SECRET_QUERY_PARAM, resolveEditorOrigin, CMSSY_EDIT_HEADER, CMSSY_EDIT_QUERY_PARAM } from '@cmssy/core';
9
9
  import { jsx } from 'react/jsx-runtime';
10
- import { resolveSiteLocales as resolveSiteLocales$1, splitLocaleFromPath as splitLocaleFromPath$1, CMSSY_LOCALE_HEADER } from '@cmssy/core/internal/locale';
11
10
 
12
11
  // src/server.ts
13
12
  function hasEditFlag(value) {
@@ -253,18 +252,21 @@ async function CmssyLayoutSlot({
253
252
  blocks,
254
253
  position,
255
254
  path,
255
+ locale: explicitLocale,
256
+ editMode,
256
257
  page = "/",
257
258
  editable: Editable,
258
259
  appContext
259
260
  }) {
260
- const editMode = await isCmssyEditMode();
261
- const [groups, siteLocales] = await Promise.all([
262
- fetchLayouts(config, page, {
263
- previewSecret: editMode ? config.draftSecret : void 0
264
- }),
265
- resolveSiteLocales$1(config)
266
- ]);
267
- const locale = path ? splitLocaleFromPath$1(path, siteLocales).locale : await localeFromHeader(siteLocales.defaultLocale);
261
+ const resolved = await resolveCmssyLayoutSlot(config, {
262
+ position,
263
+ blocks,
264
+ editMode,
265
+ page,
266
+ appContext,
267
+ ...explicitLocale !== void 0 ? { locale: explicitLocale } : { path: path ?? [] }
268
+ });
269
+ const { groups, locale, defaultLocale, enabledLocales } = resolved;
268
270
  if (!editMode) {
269
271
  return /* @__PURE__ */ jsx(
270
272
  CmssyServerLayout,
@@ -273,43 +275,28 @@ async function CmssyLayoutSlot({
273
275
  blocks,
274
276
  position,
275
277
  locale,
276
- defaultLocale: siteLocales.defaultLocale,
277
- enabledLocales: siteLocales.locales,
278
+ defaultLocale,
279
+ enabledLocales,
278
280
  config,
279
281
  appContext
280
282
  }
281
283
  );
282
284
  }
283
- const origin = resolveEditorOrigin(config.editorOrigin);
284
- const editorData = await resolveEditorLayoutBlockData({
285
- groups,
286
- blocks,
287
- position,
288
- locale,
289
- defaultLocale: siteLocales.defaultLocale,
290
- enabledLocales: siteLocales.locales,
291
- isPreview: true,
292
- config,
293
- appContext
294
- });
285
+ const origin = resolved.editorOrigin;
295
286
  return /* @__PURE__ */ jsx(
296
287
  Editable,
297
288
  {
298
289
  groups,
299
290
  position,
300
291
  locale,
301
- defaultLocale: siteLocales.defaultLocale,
302
- enabledLocales: siteLocales.locales,
292
+ defaultLocale,
293
+ enabledLocales,
303
294
  edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
304
- data: editorData.data,
305
- resolvedContent: editorData.content,
295
+ data: resolved.data,
296
+ resolvedContent: resolved.resolvedContent,
306
297
  appContext
307
298
  }
308
299
  );
309
300
  }
310
- async function localeFromHeader(defaultLocale) {
311
- const { headers: headers3 } = await import('next/headers');
312
- return (await headers3()).get(CMSSY_LOCALE_HEADER) || defaultLocale;
313
- }
314
301
 
315
302
  export { CmssyLayoutSlot, createCmssyEditPage, createCmssyPage, createDraftRoute, isCmssyEditMode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/next",
3
- "version": "10.10.0",
3
+ "version": "11.1.0",
4
4
  "description": "Next.js App Router bindings for cmssy headless sites (createCmssyPage + draft preview)",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -51,7 +51,7 @@
51
51
  "dist"
52
52
  ],
53
53
  "peerDependencies": {
54
- "@cmssy/react": "^10.0.0",
54
+ "@cmssy/react": "^11.1.0",
55
55
  "next": ">=15",
56
56
  "react": "^18.2.0 || ^19.0.0",
57
57
  "react-dom": "^18.2.0 || ^19.0.0"
@@ -65,12 +65,12 @@
65
65
  "tsup": "^8.3.0",
66
66
  "typescript": "^5.6.0",
67
67
  "vitest": "^2.1.0",
68
- "@cmssy/react": "10.10.0"
68
+ "@cmssy/react": "11.1.0"
69
69
  },
70
70
  "dependencies": {
71
71
  "@cmssy/types": "0.32.0",
72
72
  "server-only": "^0.0.1",
73
- "@cmssy/core": "10.10.0"
73
+ "@cmssy/core": "11.1.0"
74
74
  },
75
75
  "scripts": {
76
76
  "build": "tsup",