@cmssy/next 10.9.1 → 10.10.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/middleware.cjs +5 -2
- package/dist/middleware.js +5 -2
- package/dist/server.cjs +65 -0
- package/dist/server.d.cts +67 -5
- package/dist/server.d.ts +67 -5
- package/dist/server.js +67 -3
- package/package.json +3 -3
package/dist/middleware.cjs
CHANGED
|
@@ -74,8 +74,11 @@ function createCmssyProxy(config, options = {}) {
|
|
|
74
74
|
for (const write of writes) {
|
|
75
75
|
response.cookies.set(write.name, write.value, {
|
|
76
76
|
...DEFAULT_COOKIE_OPTIONS,
|
|
77
|
-
...write.
|
|
78
|
-
|
|
77
|
+
...write.options,
|
|
78
|
+
// Deletion wins over the caller's options. They will be the same
|
|
79
|
+
// options the cookie was written with, maxAge included, and honoring
|
|
80
|
+
// that here would keep an emptied cookie alive instead of removing it.
|
|
81
|
+
...write.value ? {} : { maxAge: 0 }
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
return response;
|
package/dist/middleware.js
CHANGED
|
@@ -73,8 +73,11 @@ function createCmssyProxy(config, options = {}) {
|
|
|
73
73
|
for (const write of writes) {
|
|
74
74
|
response.cookies.set(write.name, write.value, {
|
|
75
75
|
...DEFAULT_COOKIE_OPTIONS,
|
|
76
|
-
...write.
|
|
77
|
-
|
|
76
|
+
...write.options,
|
|
77
|
+
// Deletion wins over the caller's options. They will be the same
|
|
78
|
+
// options the cookie was written with, maxAge included, and honoring
|
|
79
|
+
// that here would keep an emptied cookie alive instead of removing it.
|
|
80
|
+
...write.value ? {} : { maxAge: 0 }
|
|
78
81
|
});
|
|
79
82
|
}
|
|
80
83
|
return response;
|
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,71 @@ 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
|
+
page = "/",
|
|
259
|
+
editable: Editable,
|
|
260
|
+
appContext
|
|
261
|
+
}) {
|
|
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);
|
|
270
|
+
if (!editMode) {
|
|
271
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
+
react.CmssyServerLayout,
|
|
273
|
+
{
|
|
274
|
+
groups,
|
|
275
|
+
blocks,
|
|
276
|
+
position,
|
|
277
|
+
locale: locale$1,
|
|
278
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
279
|
+
enabledLocales: siteLocales.locales,
|
|
280
|
+
config,
|
|
281
|
+
appContext
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
}
|
|
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
|
+
});
|
|
297
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
298
|
+
Editable,
|
|
299
|
+
{
|
|
300
|
+
groups,
|
|
301
|
+
position,
|
|
302
|
+
locale: locale$1,
|
|
303
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
304
|
+
enabledLocales: siteLocales.locales,
|
|
305
|
+
edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
|
|
306
|
+
data: editorData.data,
|
|
307
|
+
resolvedContent: editorData.content,
|
|
308
|
+
appContext
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
async function localeFromHeader(defaultLocale) {
|
|
313
|
+
const { headers: headers3 } = await import('next/headers');
|
|
314
|
+
return (await headers3()).get(locale.CMSSY_LOCALE_HEADER) || defaultLocale;
|
|
315
|
+
}
|
|
252
316
|
|
|
317
|
+
exports.CmssyLayoutSlot = CmssyLayoutSlot;
|
|
253
318
|
exports.createCmssyEditPage = createCmssyEditPage;
|
|
254
319
|
exports.createCmssyPage = createCmssyPage;
|
|
255
320
|
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,66 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
|
|
|
12
12
|
|
|
13
13
|
declare function isCmssyEditMode(): Promise<boolean>;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
interface CmssyLayoutSlotProps {
|
|
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
|
+
* 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.
|
|
28
|
+
*
|
|
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.
|
|
33
|
+
*/
|
|
34
|
+
path?: string[];
|
|
35
|
+
/** The page whose layout to render. Defaults to the site-wide header/footer. */
|
|
36
|
+
page?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The client wrapper around `CmssyLazyLayout`, rendered in edit mode.
|
|
39
|
+
*
|
|
40
|
+
* Required, and a component rather than a loader: the block registry has to
|
|
41
|
+
* be imported lazily ON THE CLIENT, and a function cannot cross the server
|
|
42
|
+
* boundary. Without it the editor gets a header it can select and not fill -
|
|
43
|
+
* which is why this is a type error rather than a runtime warning.
|
|
44
|
+
*/
|
|
45
|
+
editable: ComponentType<{
|
|
46
|
+
groups: CmssyLayoutGroup[];
|
|
47
|
+
position: string;
|
|
48
|
+
locale: string;
|
|
49
|
+
defaultLocale: string;
|
|
50
|
+
enabledLocales: string[];
|
|
51
|
+
edit: {
|
|
52
|
+
editorOrigin: string;
|
|
53
|
+
};
|
|
54
|
+
data?: Record<string, unknown>;
|
|
55
|
+
resolvedContent?: Record<string, Record<string, unknown>>;
|
|
56
|
+
appContext?: Record<string, unknown>;
|
|
57
|
+
}>;
|
|
58
|
+
/** Forwarded untouched to every block as `context.app`. */
|
|
59
|
+
appContext?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The site-wide header and footer, which are layout **blocks** rather than
|
|
63
|
+
* markup the app owns. Rendered the way each mode needs them:
|
|
64
|
+
*
|
|
65
|
+
* - published traffic: server-rendered blocks, no client cost;
|
|
66
|
+
* - the editor: the same blocks through the edit bridge, fetched with the
|
|
67
|
+
* preview secret and handed their server-resolved content, so a relation
|
|
68
|
+
* field shows records rather than the ids it stores.
|
|
69
|
+
*
|
|
70
|
+
* Getting any of that wrong is invisible - the site looks right while the
|
|
71
|
+
* editor shows a header it cannot fill, or the published version of one. Every
|
|
72
|
+
* app that wrote this by hand between 10.0 and 10.9 got at least one of the
|
|
73
|
+
* three wrong, which is why it is back.
|
|
74
|
+
*/
|
|
75
|
+
declare function CmssyLayoutSlot({ config, blocks, position, path, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
|
|
76
|
+
|
|
77
|
+
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,66 @@ declare function createDraftRoute(config: CmssyDraftRouteConfig): (request: Requ
|
|
|
12
12
|
|
|
13
13
|
declare function isCmssyEditMode(): Promise<boolean>;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
interface CmssyLayoutSlotProps {
|
|
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
|
+
* 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.
|
|
28
|
+
*
|
|
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.
|
|
33
|
+
*/
|
|
34
|
+
path?: string[];
|
|
35
|
+
/** The page whose layout to render. Defaults to the site-wide header/footer. */
|
|
36
|
+
page?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The client wrapper around `CmssyLazyLayout`, rendered in edit mode.
|
|
39
|
+
*
|
|
40
|
+
* Required, and a component rather than a loader: the block registry has to
|
|
41
|
+
* be imported lazily ON THE CLIENT, and a function cannot cross the server
|
|
42
|
+
* boundary. Without it the editor gets a header it can select and not fill -
|
|
43
|
+
* which is why this is a type error rather than a runtime warning.
|
|
44
|
+
*/
|
|
45
|
+
editable: ComponentType<{
|
|
46
|
+
groups: CmssyLayoutGroup[];
|
|
47
|
+
position: string;
|
|
48
|
+
locale: string;
|
|
49
|
+
defaultLocale: string;
|
|
50
|
+
enabledLocales: string[];
|
|
51
|
+
edit: {
|
|
52
|
+
editorOrigin: string;
|
|
53
|
+
};
|
|
54
|
+
data?: Record<string, unknown>;
|
|
55
|
+
resolvedContent?: Record<string, Record<string, unknown>>;
|
|
56
|
+
appContext?: Record<string, unknown>;
|
|
57
|
+
}>;
|
|
58
|
+
/** Forwarded untouched to every block as `context.app`. */
|
|
59
|
+
appContext?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The site-wide header and footer, which are layout **blocks** rather than
|
|
63
|
+
* markup the app owns. Rendered the way each mode needs them:
|
|
64
|
+
*
|
|
65
|
+
* - published traffic: server-rendered blocks, no client cost;
|
|
66
|
+
* - the editor: the same blocks through the edit bridge, fetched with the
|
|
67
|
+
* preview secret and handed their server-resolved content, so a relation
|
|
68
|
+
* field shows records rather than the ids it stores.
|
|
69
|
+
*
|
|
70
|
+
* Getting any of that wrong is invisible - the site looks right while the
|
|
71
|
+
* editor shows a header it cannot fill, or the published version of one. Every
|
|
72
|
+
* app that wrote this by hand between 10.0 and 10.9 got at least one of the
|
|
73
|
+
* three wrong, which is why it is back.
|
|
74
|
+
*/
|
|
75
|
+
declare function CmssyLayoutSlot({ config, blocks, position, path, page, editable: Editable, appContext, }: CmssyLayoutSlotProps): Promise<react_jsx_runtime.JSX.Element>;
|
|
76
|
+
|
|
77
|
+
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, CMSSY_LOCALE_HEADER } from '@cmssy/core/internal/locale';
|
|
10
11
|
|
|
11
12
|
// src/server.ts
|
|
12
13
|
function hasEditFlag(value) {
|
|
@@ -247,5 +248,68 @@ 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
|
+
page = "/",
|
|
257
|
+
editable: Editable,
|
|
258
|
+
appContext
|
|
259
|
+
}) {
|
|
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);
|
|
268
|
+
if (!editMode) {
|
|
269
|
+
return /* @__PURE__ */ jsx(
|
|
270
|
+
CmssyServerLayout,
|
|
271
|
+
{
|
|
272
|
+
groups,
|
|
273
|
+
blocks,
|
|
274
|
+
position,
|
|
275
|
+
locale,
|
|
276
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
277
|
+
enabledLocales: siteLocales.locales,
|
|
278
|
+
config,
|
|
279
|
+
appContext
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
}
|
|
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
|
+
});
|
|
295
|
+
return /* @__PURE__ */ jsx(
|
|
296
|
+
Editable,
|
|
297
|
+
{
|
|
298
|
+
groups,
|
|
299
|
+
position,
|
|
300
|
+
locale,
|
|
301
|
+
defaultLocale: siteLocales.defaultLocale,
|
|
302
|
+
enabledLocales: siteLocales.locales,
|
|
303
|
+
edit: { editorOrigin: (Array.isArray(origin) ? origin[0] : origin) ?? "" },
|
|
304
|
+
data: editorData.data,
|
|
305
|
+
resolvedContent: editorData.content,
|
|
306
|
+
appContext
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
async function localeFromHeader(defaultLocale) {
|
|
311
|
+
const { headers: headers3 } = await import('next/headers');
|
|
312
|
+
return (await headers3()).get(CMSSY_LOCALE_HEADER) || defaultLocale;
|
|
313
|
+
}
|
|
250
314
|
|
|
251
|
-
export { createCmssyEditPage, createCmssyPage, createDraftRoute, isCmssyEditMode };
|
|
315
|
+
export { CmssyLayoutSlot, createCmssyEditPage, createCmssyPage, createDraftRoute, isCmssyEditMode };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/next",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.10.0",
|
|
4
4
|
"description": "Next.js App Router bindings for cmssy headless sites (createCmssyPage + draft preview)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cmssy",
|
|
@@ -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.
|
|
68
|
+
"@cmssy/react": "10.10.0"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"@cmssy/types": "0.32.0",
|
|
72
72
|
"server-only": "^0.0.1",
|
|
73
|
-
"@cmssy/core": "10.
|
|
73
|
+
"@cmssy/core": "10.10.0"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"build": "tsup",
|