@vexcms/next 0.1.0-alpha.6 → 0.1.0-alpha.7
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.
|
@@ -26,7 +26,8 @@ import type { AdminUser } from "@vexcms/react";
|
|
|
26
26
|
* @param props.config - The resolved VexCMS config from `vex.config.ts` (raw)
|
|
27
27
|
* @param props.children - The page content from `[[...slug]]/page.tsx`
|
|
28
28
|
* @param props.user - Current user for the admin shell
|
|
29
|
-
*
|
|
29
|
+
* @returns The rendered admin shell, wrapping `children` in the sanitized-config
|
|
30
|
+
* client boundary ({@link NextAdminLayoutClient}).
|
|
30
31
|
* @example
|
|
31
32
|
* ```tsx
|
|
32
33
|
* // app/admin/layout.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAdminLayout.d.ts","sourceRoot":"","sources":["../src/NextAdminLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C
|
|
1
|
+
{"version":3,"file":"NextAdminLayout.d.ts","sourceRoot":"","sources":["../src/NextAdminLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,wCAmBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/NextAdminLayout.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { VexConfig } from \"@vexcms/core\";\nimport { sanitizeConfigForClient } from \"@vexcms/core\";\nimport type { AdminUser } from \"@vexcms/react\";\nimport { NextAdminLayoutClient } from \"./NextAdminLayoutClient\";\nimport { cookies } from \"next/headers\";\n\n/**\n * Next.js admin layout shell for VexCMS.\n *\n * A **server component** that sits on the server→client boundary for the admin\n * panel. It sanitizes the resolved `vex.config` with `sanitizeConfigForClient`\n * — stripping storage adapter class instances, functions, and React components\n * — *before* the config is handed to the client leaf `NextAdminLayoutClient`.\n *\n * This placement is the whole point: React serializes props when a server\n * component renders a client component, so the sanitize **must** happen on the\n * server side of that edge. Sanitizing inside the client component would run\n * too late — the raw config would already have failed to serialize.\n *\n * The client leaf handles everything that needs the browser (`usePathname`,\n * `NuqsAdapter`, `NextLink`/`NextImage`); this wrapper does no client work.\n *\n * Render it from your admin `layout.tsx`. Because this is a server component,\n * your `layout.tsx` may itself be an `async` server component (e.g. to run auth\n * checks) and pass the **raw** `vex.config` straight through — no sanitize\n * needed on the application side.\n *\n * @param props - Layout props\n * @param props.config - The resolved VexCMS config from `vex.config.ts` (raw)\n * @param props.children - The page content from `[[...slug]]/page.tsx`\n * @param props.user - Current user for the admin shell\n
|
|
1
|
+
{"version":3,"sources":["../src/NextAdminLayout.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { VexConfig } from \"@vexcms/core\";\nimport { sanitizeConfigForClient } from \"@vexcms/core\";\nimport type { AdminUser } from \"@vexcms/react\";\nimport { NextAdminLayoutClient } from \"./NextAdminLayoutClient\";\nimport { cookies } from \"next/headers\";\n\n/**\n * Next.js admin layout shell for VexCMS.\n *\n * A **server component** that sits on the server→client boundary for the admin\n * panel. It sanitizes the resolved `vex.config` with `sanitizeConfigForClient`\n * — stripping storage adapter class instances, functions, and React components\n * — *before* the config is handed to the client leaf `NextAdminLayoutClient`.\n *\n * This placement is the whole point: React serializes props when a server\n * component renders a client component, so the sanitize **must** happen on the\n * server side of that edge. Sanitizing inside the client component would run\n * too late — the raw config would already have failed to serialize.\n *\n * The client leaf handles everything that needs the browser (`usePathname`,\n * `NuqsAdapter`, `NextLink`/`NextImage`); this wrapper does no client work.\n *\n * Render it from your admin `layout.tsx`. Because this is a server component,\n * your `layout.tsx` may itself be an `async` server component (e.g. to run auth\n * checks) and pass the **raw** `vex.config` straight through — no sanitize\n * needed on the application side.\n *\n * @param props - Layout props\n * @param props.config - The resolved VexCMS config from `vex.config.ts` (raw)\n * @param props.children - The page content from `[[...slug]]/page.tsx`\n * @param props.user - Current user for the admin shell\n * @returns The rendered admin shell, wrapping `children` in the sanitized-config\n * client boundary ({@link NextAdminLayoutClient}).\n * @example\n * ```tsx\n * // app/admin/layout.tsx\n * import { NextAdminLayout } from \"@vexcms/next/client\";\n * import config from \"~/vex.config\";\n * import { getCurrentUser } from \"~/auth/serverUtils\";\n *\n * export default async function AdminLayout({ children }: { children: ReactNode }) {\n * const user = await getCurrentUser();\n * return (\n * <NextAdminLayout config={config} user={user ?? undefined}>\n * {children}\n * </NextAdminLayout>\n * );\n * }\n * ```\n */\nexport async function NextAdminLayout(props: {\n config: VexConfig;\n children: ReactNode;\n user?: AdminUser;\n organization?: Record<string, unknown>;\n}) {\n // Sanitize on the SERVER side of the server→client boundary, before the\n // config is serialized as a prop into the client leaf. This removes the\n // storage adapter class instances that would otherwise crash RSC\n // serialization (\"Classes or null prototypes are not supported\").\n const clientConfig = sanitizeConfigForClient(props.config);\n const cookieStore = await cookies();\n const sidebarOpen = String(cookieStore.get(\"sidebar_state\")?.value) === \"true\";\n\n return (\n <NextAdminLayoutClient\n config={clientConfig}\n user={props.user}\n organization={props.organization}\n sidebarOpen={sidebarOpen}\n >\n {props.children}\n </NextAdminLayoutClient>\n );\n}\n"],"mappings":";AAEA,SAAS,+BAA+B;AAExC,SAAS,6BAA6B;AACtC,SAAS,eAAe;AA6DpB;AAfJ,eAAsB,gBAAgB,OAKnC;AAKD,QAAM,eAAe,wBAAwB,MAAM,MAAM;AACzD,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,cAAc,OAAO,YAAY,IAAI,eAAe,GAAG,KAAK,MAAM;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ;AAAA,MACR,MAAM,MAAM;AAAA,MACZ,cAAc,MAAM;AAAA,MACpB;AAAA,MAEC,gBAAM;AAAA;AAAA,EACT;AAEJ;","names":[]}
|
|
@@ -24,6 +24,9 @@ import { type AdminUser } from "@vexcms/react";
|
|
|
24
24
|
* @param props.config - Sanitized config, safe to serialize across the boundary
|
|
25
25
|
* @param props.children - The page content from `[[...slug]]/page.tsx`
|
|
26
26
|
* @param props.user - Current user for the admin shell
|
|
27
|
+
* @returns The admin shell rendered from `children`, wrapped in `NuqsAdapter`
|
|
28
|
+
* and the shared `AdminLayout`, wired with the active slug/document id derived
|
|
29
|
+
* from `usePathname()` and Next.js `Link`/`Image` components.
|
|
27
30
|
*/
|
|
28
31
|
export declare function NextAdminLayoutClient(props: {
|
|
29
32
|
config: ClientVexConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAdminLayoutClient.d.ts","sourceRoot":"","sources":["../src/NextAdminLayoutClient.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE5D
|
|
1
|
+
{"version":3,"file":"NextAdminLayoutClient.d.ts","sourceRoot":"","sources":["../src/NextAdminLayoutClient.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,+BAwBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/NextAdminLayoutClient.tsx"],"sourcesContent":["\"use client\";\n// \"use client\" is injected by the tsup build banner for this entry (see\n// tsup.config.ts) so the emitted module carries the client boundary.\nimport type { ReactNode } from \"react\";\nimport type { ClientVexConfig } from \"@vexcms/core\";\nimport { usePathname } from \"next/navigation\";\nimport NextLink from \"next/link\";\nimport NextImage from \"next/image\";\nimport { NuqsAdapter } from \"nuqs/adapters/next/app\";\nimport { AdminLayout, type AdminUser } from \"@vexcms/react\";\n\n/**\n * Client leaf for the Next.js admin layout.\n *\n * Owns all client-only wiring that cannot run on the server:\n * - `usePathname()` to derive the active collection slug / document id for\n * sidebar highlighting (Next.js layouts do not receive route params).\n * - `NuqsAdapter` (`nuqs/adapters/next/app`) so URL state works inside the\n * admin routes.\n * - `NextLink` / `NextImage` passed as framework components so every\n * `VexLink`/`VexImage` uses Next.js routing and image optimisation.\n *\n * **Receives an already-sanitized `ClientVexConfig`.** The server wrapper\n * ({@link NextAdminLayout}) calls `sanitizeConfigForClient` before this\n * component is reached, so no non-serializable values (storage adapter class\n * instances, functions, React components) cross the server→client boundary.\n *\n * This component is internal to `@vexcms/next` — applications render\n * {@link NextAdminLayout} instead.\n *\n * @param props - Layout props\n * @param props.config - Sanitized config, safe to serialize across the boundary\n * @param props.children - The page content from `[[...slug]]/page.tsx`\n * @param props.user - Current user for the admin shell\n */\nexport function NextAdminLayoutClient(props: {\n config: ClientVexConfig;\n children: ReactNode;\n user?: AdminUser;\n organization?: Record<string, unknown>;\n sidebarOpen?: boolean;\n}) {\n const pathname = usePathname();\n // pathname: \"/admin\", \"/admin/posts\", \"/admin/posts/123\"\n // Split on \"/\" and take the segment after \"admin\"\n const segments = pathname.split(\"/\").filter(Boolean);\n const activeSlug = segments[1]; // undefined on /admin, \"posts\" on /admin/posts\n const activeDocID = segments[2];\n\n return (\n <NuqsAdapter>\n <AdminLayout\n config={props.config}\n activeSlug={activeSlug}\n components={{ Link: NextLink, Image: NextImage }}\n pathname={pathname}\n activeDocID={activeDocID}\n user={props.user}\n organization={props.organization}\n sidebarOpen={props.sidebarOpen}\n >\n {props.children}\n </AdminLayout>\n </NuqsAdapter>\n );\n}\n"],"mappings":";;;;AAKA,SAAS,mBAAmB;AAC5B,OAAO,cAAc;AACrB,OAAO,eAAe;AACtB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmC;
|
|
1
|
+
{"version":3,"sources":["../src/NextAdminLayoutClient.tsx"],"sourcesContent":["\"use client\";\n// \"use client\" is injected by the tsup build banner for this entry (see\n// tsup.config.ts) so the emitted module carries the client boundary.\nimport type { ReactNode } from \"react\";\nimport type { ClientVexConfig } from \"@vexcms/core\";\nimport { usePathname } from \"next/navigation\";\nimport NextLink from \"next/link\";\nimport NextImage from \"next/image\";\nimport { NuqsAdapter } from \"nuqs/adapters/next/app\";\nimport { AdminLayout, type AdminUser } from \"@vexcms/react\";\n\n/**\n * Client leaf for the Next.js admin layout.\n *\n * Owns all client-only wiring that cannot run on the server:\n * - `usePathname()` to derive the active collection slug / document id for\n * sidebar highlighting (Next.js layouts do not receive route params).\n * - `NuqsAdapter` (`nuqs/adapters/next/app`) so URL state works inside the\n * admin routes.\n * - `NextLink` / `NextImage` passed as framework components so every\n * `VexLink`/`VexImage` uses Next.js routing and image optimisation.\n *\n * **Receives an already-sanitized `ClientVexConfig`.** The server wrapper\n * ({@link NextAdminLayout}) calls `sanitizeConfigForClient` before this\n * component is reached, so no non-serializable values (storage adapter class\n * instances, functions, React components) cross the server→client boundary.\n *\n * This component is internal to `@vexcms/next` — applications render\n * {@link NextAdminLayout} instead.\n *\n * @param props - Layout props\n * @param props.config - Sanitized config, safe to serialize across the boundary\n * @param props.children - The page content from `[[...slug]]/page.tsx`\n * @param props.user - Current user for the admin shell\n * @returns The admin shell rendered from `children`, wrapped in `NuqsAdapter`\n * and the shared `AdminLayout`, wired with the active slug/document id derived\n * from `usePathname()` and Next.js `Link`/`Image` components.\n */\nexport function NextAdminLayoutClient(props: {\n config: ClientVexConfig;\n children: ReactNode;\n user?: AdminUser;\n organization?: Record<string, unknown>;\n sidebarOpen?: boolean;\n}) {\n const pathname = usePathname();\n // pathname: \"/admin\", \"/admin/posts\", \"/admin/posts/123\"\n // Split on \"/\" and take the segment after \"admin\"\n const segments = pathname.split(\"/\").filter(Boolean);\n const activeSlug = segments[1]; // undefined on /admin, \"posts\" on /admin/posts\n const activeDocID = segments[2];\n\n return (\n <NuqsAdapter>\n <AdminLayout\n config={props.config}\n activeSlug={activeSlug}\n components={{ Link: NextLink, Image: NextImage }}\n pathname={pathname}\n activeDocID={activeDocID}\n user={props.user}\n organization={props.organization}\n sidebarOpen={props.sidebarOpen}\n >\n {props.children}\n </AdminLayout>\n </NuqsAdapter>\n );\n}\n"],"mappings":";;;;AAKA,SAAS,mBAAmB;AAC5B,OAAO,cAAc;AACrB,OAAO,eAAe;AACtB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmC;AA6CtC;AAhBC,SAAS,sBAAsB,OAMnC;AACD,QAAM,WAAW,YAAY;AAG7B,QAAM,WAAW,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACnD,QAAM,aAAa,SAAS,CAAC;AAC7B,QAAM,cAAc,SAAS,CAAC;AAE9B,SACE,oBAAC,eACC;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ,MAAM;AAAA,MACd;AAAA,MACA,YAAY,EAAE,MAAM,UAAU,OAAO,UAAU;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,cAAc,MAAM;AAAA,MACpB,aAAa,MAAM;AAAA,MAElB,gBAAM;AAAA;AAAA,EACT,GACF;AAEJ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vexcms/next",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
4
|
"description": "Next.js adapter and admin routes for VexCMS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"lucide-react": "0.577.0",
|
|
54
|
-
"@vexcms/
|
|
55
|
-
"@vexcms/
|
|
54
|
+
"@vexcms/react": "0.1.0-alpha.7",
|
|
55
|
+
"@vexcms/core": "0.1.0-alpha.7"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@convex-dev/react-query": "0.1.0",
|