@cmssy/next 10.9.2 → 11.0.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 +62 -0
- package/dist/server.d.cts +84 -5
- package/dist/server.d.ts +84 -5
- package/dist/server.js +64 -3
- package/package.json +4 -4
package/dist/server.cjs
CHANGED
|
@@ -9,6 +9,7 @@ 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');
|
|
12
13
|
|
|
13
14
|
// src/server.ts
|
|
14
15
|
function hasEditFlag(value) {
|
|
@@ -249,7 +250,68 @@ async function isCmssyEditMode() {
|
|
|
249
250
|
const h = await headers.headers();
|
|
250
251
|
return h.get(core.CMSSY_EDIT_HEADER) === "1";
|
|
251
252
|
}
|
|
253
|
+
async function CmssyLayoutSlot({
|
|
254
|
+
config,
|
|
255
|
+
blocks,
|
|
256
|
+
position,
|
|
257
|
+
path,
|
|
258
|
+
locale: explicitLocale,
|
|
259
|
+
editMode,
|
|
260
|
+
page = "/",
|
|
261
|
+
editable: Editable,
|
|
262
|
+
appContext
|
|
263
|
+
}) {
|
|
264
|
+
const [groups, siteLocales] = await Promise.all([
|
|
265
|
+
internal.fetchLayouts(config, page, {
|
|
266
|
+
previewSecret: editMode ? config.draftSecret : void 0
|
|
267
|
+
}),
|
|
268
|
+
locale.resolveSiteLocales(config)
|
|
269
|
+
]);
|
|
270
|
+
const locale$1 = explicitLocale ?? locale.splitLocaleFromPath(path ?? [], siteLocales).locale;
|
|
271
|
+
if (!editMode) {
|
|
272
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
273
|
+
react.CmssyServerLayout,
|
|
274
|
+
{
|
|
275
|
+
groups,
|
|
276
|
+
blocks,
|
|
277
|
+
position,
|
|
278
|
+
locale: locale$1,
|
|
279
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
280
|
+
enabledLocales: siteLocales.locales,
|
|
281
|
+
config,
|
|
282
|
+
appContext
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
const origin = core.resolveEditorOrigin(config.editorOrigin);
|
|
287
|
+
const editorData = await react.resolveEditorLayoutBlockData({
|
|
288
|
+
groups,
|
|
289
|
+
blocks,
|
|
290
|
+
position,
|
|
291
|
+
locale: locale$1,
|
|
292
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
293
|
+
enabledLocales: siteLocales.locales,
|
|
294
|
+
isPreview: true,
|
|
295
|
+
config,
|
|
296
|
+
appContext
|
|
297
|
+
});
|
|
298
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
299
|
+
Editable,
|
|
300
|
+
{
|
|
301
|
+
groups,
|
|
302
|
+
position,
|
|
303
|
+
locale: locale$1,
|
|
304
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
305
|
+
enabledLocales: siteLocales.locales,
|
|
306
|
+
edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
|
|
307
|
+
data: editorData.data,
|
|
308
|
+
resolvedContent: editorData.content,
|
|
309
|
+
appContext
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
}
|
|
252
313
|
|
|
314
|
+
exports.CmssyLayoutSlot = CmssyLayoutSlot;
|
|
253
315
|
exports.createCmssyEditPage = createCmssyEditPage;
|
|
254
316
|
exports.createCmssyPage = createCmssyPage;
|
|
255
317
|
exports.createDraftRoute = createDraftRoute;
|
package/dist/server.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { C as CmssyAppContext, a as CmssyEditorProps, b as CreateCmssyPageOptions, c as createCmssyEditPage, d as createCmssyPage } from './index-B64zk2X7.cjs';
|
|
2
|
-
import { CmssyConfig } from '@cmssy/core';
|
|
3
|
-
import 'react/jsx-runtime';
|
|
4
|
-
import 'react';
|
|
5
|
-
import '@cmssy/react';
|
|
2
|
+
import { CmssyConfig, LayoutPosition } from '@cmssy/core';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ComponentType } from 'react';
|
|
5
|
+
import { BlockDefinition, CmssyLayoutGroup } from '@cmssy/react';
|
|
6
6
|
import '@cmssy/react/client';
|
|
7
7
|
|
|
8
8
|
type CmssyDraftRouteConfig = Pick<CmssyConfig, "draftSecret"> & {
|
|
@@ -12,4 +12,83 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
|
|
|
12
12
|
|
|
13
13
|
declare function isCmssyEditMode(): Promise<boolean>;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
interface CmssyLayoutSlotBaseProps {
|
|
16
|
+
config: CmssyConfig;
|
|
17
|
+
blocks: BlockDefinition[];
|
|
18
|
+
/**
|
|
19
|
+
* Which layout position to render. Six exist - `top`, `header`,
|
|
20
|
+
* `sidebar_left`, `sidebar_right`, `footer`, `bottom` - and most sites use
|
|
21
|
+
* two of them; the type is what tells you about the other four.
|
|
22
|
+
*/
|
|
23
|
+
position: LayoutPosition;
|
|
24
|
+
/**
|
|
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.
|
|
29
|
+
*
|
|
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.
|
|
32
|
+
*/
|
|
33
|
+
editMode: boolean;
|
|
34
|
+
/** The page whose layout to render. Defaults to the site-wide header/footer. */
|
|
35
|
+
page?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The client wrapper around `CmssyLazyLayout`, rendered in edit mode.
|
|
38
|
+
*
|
|
39
|
+
* Required, and a component rather than a loader: the block registry has to
|
|
40
|
+
* be imported lazily ON THE CLIENT, and a function cannot cross the server
|
|
41
|
+
* boundary. Without it the editor gets a header it can select and not fill -
|
|
42
|
+
* which is why this is a type error rather than a runtime warning.
|
|
43
|
+
*/
|
|
44
|
+
editable: ComponentType<{
|
|
45
|
+
groups: CmssyLayoutGroup[];
|
|
46
|
+
position: string;
|
|
47
|
+
locale: string;
|
|
48
|
+
defaultLocale: string;
|
|
49
|
+
enabledLocales: string[];
|
|
50
|
+
edit: {
|
|
51
|
+
editorOrigin: string;
|
|
52
|
+
};
|
|
53
|
+
data?: Record<string, unknown>;
|
|
54
|
+
resolvedContent?: Record<string, Record<string, unknown>>;
|
|
55
|
+
appContext?: Record<string, unknown>;
|
|
56
|
+
}>;
|
|
57
|
+
/** Forwarded untouched to every block as `context.app`. */
|
|
58
|
+
appContext?: Record<string, unknown>;
|
|
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;
|
|
78
|
+
/**
|
|
79
|
+
* The site-wide header and footer, which are layout **blocks** rather than
|
|
80
|
+
* markup the app owns. Rendered the way each mode needs them:
|
|
81
|
+
*
|
|
82
|
+
* - published traffic: server-rendered blocks, no client cost;
|
|
83
|
+
* - the editor: the same blocks through the edit bridge, fetched with the
|
|
84
|
+
* preview secret and handed their server-resolved content, so a relation
|
|
85
|
+
* field shows records rather than the ids it stores.
|
|
86
|
+
*
|
|
87
|
+
* Getting any of that wrong is invisible - the site looks right while the
|
|
88
|
+
* editor shows a header it cannot fill, or the published version of one. Every
|
|
89
|
+
* app that wrote this by hand between 10.0 and 10.9 got at least one of the
|
|
90
|
+
* three wrong, which is why it is back.
|
|
91
|
+
*/
|
|
92
|
+
declare function CmssyLayoutSlot({ config, blocks, position, path, locale: explicitLocale, editMode, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
|
|
93
|
+
|
|
94
|
+
export { type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, createDraftRoute, isCmssyEditMode };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { C as CmssyAppContext, a as CmssyEditorProps, b as CreateCmssyPageOptions, c as createCmssyEditPage, d as createCmssyPage } from './index-B64zk2X7.js';
|
|
2
|
-
import { CmssyConfig } from '@cmssy/core';
|
|
3
|
-
import 'react/jsx-runtime';
|
|
4
|
-
import 'react';
|
|
5
|
-
import '@cmssy/react';
|
|
2
|
+
import { CmssyConfig, LayoutPosition } from '@cmssy/core';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ComponentType } from 'react';
|
|
5
|
+
import { BlockDefinition, CmssyLayoutGroup } from '@cmssy/react';
|
|
6
6
|
import '@cmssy/react/client';
|
|
7
7
|
|
|
8
8
|
type CmssyDraftRouteConfig = Pick<CmssyConfig, "draftSecret"> & {
|
|
@@ -12,4 +12,83 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
|
|
|
12
12
|
|
|
13
13
|
declare function isCmssyEditMode(): Promise<boolean>;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
interface CmssyLayoutSlotBaseProps {
|
|
16
|
+
config: CmssyConfig;
|
|
17
|
+
blocks: BlockDefinition[];
|
|
18
|
+
/**
|
|
19
|
+
* Which layout position to render. Six exist - `top`, `header`,
|
|
20
|
+
* `sidebar_left`, `sidebar_right`, `footer`, `bottom` - and most sites use
|
|
21
|
+
* two of them; the type is what tells you about the other four.
|
|
22
|
+
*/
|
|
23
|
+
position: LayoutPosition;
|
|
24
|
+
/**
|
|
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.
|
|
29
|
+
*
|
|
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.
|
|
32
|
+
*/
|
|
33
|
+
editMode: boolean;
|
|
34
|
+
/** The page whose layout to render. Defaults to the site-wide header/footer. */
|
|
35
|
+
page?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The client wrapper around `CmssyLazyLayout`, rendered in edit mode.
|
|
38
|
+
*
|
|
39
|
+
* Required, and a component rather than a loader: the block registry has to
|
|
40
|
+
* be imported lazily ON THE CLIENT, and a function cannot cross the server
|
|
41
|
+
* boundary. Without it the editor gets a header it can select and not fill -
|
|
42
|
+
* which is why this is a type error rather than a runtime warning.
|
|
43
|
+
*/
|
|
44
|
+
editable: ComponentType<{
|
|
45
|
+
groups: CmssyLayoutGroup[];
|
|
46
|
+
position: string;
|
|
47
|
+
locale: string;
|
|
48
|
+
defaultLocale: string;
|
|
49
|
+
enabledLocales: string[];
|
|
50
|
+
edit: {
|
|
51
|
+
editorOrigin: string;
|
|
52
|
+
};
|
|
53
|
+
data?: Record<string, unknown>;
|
|
54
|
+
resolvedContent?: Record<string, Record<string, unknown>>;
|
|
55
|
+
appContext?: Record<string, unknown>;
|
|
56
|
+
}>;
|
|
57
|
+
/** Forwarded untouched to every block as `context.app`. */
|
|
58
|
+
appContext?: Record<string, unknown>;
|
|
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;
|
|
78
|
+
/**
|
|
79
|
+
* The site-wide header and footer, which are layout **blocks** rather than
|
|
80
|
+
* markup the app owns. Rendered the way each mode needs them:
|
|
81
|
+
*
|
|
82
|
+
* - published traffic: server-rendered blocks, no client cost;
|
|
83
|
+
* - the editor: the same blocks through the edit bridge, fetched with the
|
|
84
|
+
* preview secret and handed their server-resolved content, so a relation
|
|
85
|
+
* field shows records rather than the ids it stores.
|
|
86
|
+
*
|
|
87
|
+
* Getting any of that wrong is invisible - the site looks right while the
|
|
88
|
+
* editor shows a header it cannot fill, or the published version of one. Every
|
|
89
|
+
* app that wrote this by hand between 10.0 and 10.9 got at least one of the
|
|
90
|
+
* three wrong, which is why it is back.
|
|
91
|
+
*/
|
|
92
|
+
declare function CmssyLayoutSlot({ config, blocks, position, path, locale: explicitLocale, editMode, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
|
|
93
|
+
|
|
94
|
+
export { type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, createDraftRoute, isCmssyEditMode };
|
package/dist/server.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
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 } from '@cmssy/react';
|
|
4
|
+
import { createCmssyClient, CmssyServerPage, CmssyServerLayout, resolveEditorLayoutBlockData } 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 } from '@cmssy/core/internal';
|
|
7
|
+
import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, fetchPage, resolveForms, toCspOrigin, cmssySecretsMatch, fetchLayouts } 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 } from '@cmssy/core/internal/locale';
|
|
10
11
|
|
|
11
12
|
// src/server.ts
|
|
12
13
|
function hasEditFlag(value) {
|
|
@@ -247,5 +248,65 @@ async function isCmssyEditMode() {
|
|
|
247
248
|
const h = await headers();
|
|
248
249
|
return h.get(CMSSY_EDIT_HEADER) === "1";
|
|
249
250
|
}
|
|
251
|
+
async function CmssyLayoutSlot({
|
|
252
|
+
config,
|
|
253
|
+
blocks,
|
|
254
|
+
position,
|
|
255
|
+
path,
|
|
256
|
+
locale: explicitLocale,
|
|
257
|
+
editMode,
|
|
258
|
+
page = "/",
|
|
259
|
+
editable: Editable,
|
|
260
|
+
appContext
|
|
261
|
+
}) {
|
|
262
|
+
const [groups, siteLocales] = await Promise.all([
|
|
263
|
+
fetchLayouts(config, page, {
|
|
264
|
+
previewSecret: editMode ? config.draftSecret : void 0
|
|
265
|
+
}),
|
|
266
|
+
resolveSiteLocales$1(config)
|
|
267
|
+
]);
|
|
268
|
+
const locale = explicitLocale ?? splitLocaleFromPath$1(path ?? [], siteLocales).locale;
|
|
269
|
+
if (!editMode) {
|
|
270
|
+
return /* @__PURE__ */ jsx(
|
|
271
|
+
CmssyServerLayout,
|
|
272
|
+
{
|
|
273
|
+
groups,
|
|
274
|
+
blocks,
|
|
275
|
+
position,
|
|
276
|
+
locale,
|
|
277
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
278
|
+
enabledLocales: siteLocales.locales,
|
|
279
|
+
config,
|
|
280
|
+
appContext
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
const origin = resolveEditorOrigin(config.editorOrigin);
|
|
285
|
+
const editorData = await resolveEditorLayoutBlockData({
|
|
286
|
+
groups,
|
|
287
|
+
blocks,
|
|
288
|
+
position,
|
|
289
|
+
locale,
|
|
290
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
291
|
+
enabledLocales: siteLocales.locales,
|
|
292
|
+
isPreview: true,
|
|
293
|
+
config,
|
|
294
|
+
appContext
|
|
295
|
+
});
|
|
296
|
+
return /* @__PURE__ */ jsx(
|
|
297
|
+
Editable,
|
|
298
|
+
{
|
|
299
|
+
groups,
|
|
300
|
+
position,
|
|
301
|
+
locale,
|
|
302
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
303
|
+
enabledLocales: siteLocales.locales,
|
|
304
|
+
edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
|
|
305
|
+
data: editorData.data,
|
|
306
|
+
resolvedContent: editorData.content,
|
|
307
|
+
appContext
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
}
|
|
250
311
|
|
|
251
|
-
export { createCmssyEditPage, createCmssyPage, createDraftRoute, isCmssyEditMode };
|
|
312
|
+
export { CmssyLayoutSlot, createCmssyEditPage, createCmssyPage, createDraftRoute, isCmssyEditMode };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/next",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.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": "^
|
|
54
|
+
"@cmssy/react": "^11.0.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": "
|
|
68
|
+
"@cmssy/react": "11.0.0"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"@cmssy/types": "0.32.0",
|
|
72
72
|
"server-only": "^0.0.1",
|
|
73
|
-
"@cmssy/core": "
|
|
73
|
+
"@cmssy/core": "11.0.0"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"build": "tsup",
|