Initial commit
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from "next";
|
||||
|
||||
import config from "@payload-config";
|
||||
import { NotFoundPage, generatePageMetadata } from "@payloadcms/next/views";
|
||||
import { importMap } from "../importMap";
|
||||
|
||||
type Args = {
|
||||
params: Promise<{ segments: string[] }>;
|
||||
searchParams: Promise<Record<string, string | string[]>>;
|
||||
};
|
||||
|
||||
export const generateMetadata = ({
|
||||
params,
|
||||
searchParams,
|
||||
}: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams });
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) =>
|
||||
NotFoundPage({ config, importMap, params, searchParams });
|
||||
|
||||
export default NotFound;
|
||||
23
apps/cms/src/app/(payload)/admin/[[...segments]]/page.tsx
Normal file
23
apps/cms/src/app/(payload)/admin/[[...segments]]/page.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from "next";
|
||||
|
||||
import config from "@payload-config";
|
||||
import { RootPage, generatePageMetadata } from "@payloadcms/next/views";
|
||||
import { importMap } from "../importMap";
|
||||
|
||||
type Args = {
|
||||
params: Promise<{ segments: string[] }>;
|
||||
searchParams: Promise<Record<string, string | string[]>>;
|
||||
};
|
||||
|
||||
export const generateMetadata = ({
|
||||
params,
|
||||
searchParams,
|
||||
}: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams });
|
||||
|
||||
const Page = ({ params, searchParams }: Args) =>
|
||||
RootPage({ config, importMap, params, searchParams });
|
||||
|
||||
export default Page;
|
||||
52
apps/cms/src/app/(payload)/admin/importMap.js
Normal file
52
apps/cms/src/app/(payload)/admin/importMap.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc'
|
||||
|
||||
/** @type {Record<string, any>} */
|
||||
export const importMap = {
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1
|
||||
}
|
||||
19
apps/cms/src/app/(payload)/api/[...slug]/route.ts
Normal file
19
apps/cms/src/app/(payload)/api/[...slug]/route.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from "@payload-config";
|
||||
import "@payloadcms/next/css";
|
||||
import {
|
||||
REST_DELETE,
|
||||
REST_GET,
|
||||
REST_OPTIONS,
|
||||
REST_PATCH,
|
||||
REST_POST,
|
||||
REST_PUT,
|
||||
} from "@payloadcms/next/routes";
|
||||
|
||||
export const GET = REST_GET(config);
|
||||
export const POST = REST_POST(config);
|
||||
export const DELETE = REST_DELETE(config);
|
||||
export const PATCH = REST_PATCH(config);
|
||||
export const PUT = REST_PUT(config);
|
||||
export const OPTIONS = REST_OPTIONS(config);
|
||||
6
apps/cms/src/app/(payload)/api/graphql/route.ts
Normal file
6
apps/cms/src/app/(payload)/api/graphql/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from "@payload-config";
|
||||
import { GRAPHQL_POST } from "@payloadcms/next/routes";
|
||||
|
||||
export const POST = GRAPHQL_POST(config);
|
||||
1
apps/cms/src/app/(payload)/custom.scss
Normal file
1
apps/cms/src/app/(payload)/custom.scss
Normal file
@@ -0,0 +1 @@
|
||||
// Custom admin panel styles
|
||||
35
apps/cms/src/app/(payload)/layout.tsx
Normal file
35
apps/cms/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from "@payload-config";
|
||||
import "@payloadcms/next/css";
|
||||
import type { ServerFunctionClient } from "payload";
|
||||
import { handleServerFunctions, RootLayout } from "@payloadcms/next/layouts";
|
||||
import React from "react";
|
||||
|
||||
import { importMap } from "./admin/importMap.js";
|
||||
import "./custom.scss";
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const serverFunction: ServerFunctionClient = async function (args) {
|
||||
"use server";
|
||||
return handleServerFunctions({
|
||||
...args,
|
||||
config,
|
||||
importMap,
|
||||
});
|
||||
};
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout
|
||||
config={config}
|
||||
importMap={importMap}
|
||||
serverFunction={serverFunction}
|
||||
>
|
||||
{children}
|
||||
</RootLayout>
|
||||
);
|
||||
|
||||
export default Layout;
|
||||
81
apps/cms/src/middleware.test.ts
Normal file
81
apps/cms/src/middleware.test.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
|
||||
const responseMock = vi.hoisted(() => {
|
||||
function makeResponseMock() {
|
||||
const store = new Map<string, string>();
|
||||
return {
|
||||
_store: store,
|
||||
headers: {
|
||||
set: vi.fn((k: string, v: string) => store.set(k, v)),
|
||||
get: vi.fn((k: string) => store.get(k) ?? null),
|
||||
},
|
||||
};
|
||||
}
|
||||
return { makeResponseMock };
|
||||
});
|
||||
|
||||
vi.mock("next/server", () => ({
|
||||
NextResponse: {
|
||||
next: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
import { middleware } from "../middleware";
|
||||
|
||||
const ALL_SIX_HEADERS = [
|
||||
"Strict-Transport-Security",
|
||||
"X-Frame-Options",
|
||||
"X-Content-Type-Options",
|
||||
"Referrer-Policy",
|
||||
"Permissions-Policy",
|
||||
"Content-Security-Policy",
|
||||
] as const;
|
||||
|
||||
function makeRequest(): NextRequest {
|
||||
return { headers: new Headers() } as unknown as NextRequest;
|
||||
}
|
||||
|
||||
describe("cms middleware", () => {
|
||||
let mock: ReturnType<typeof responseMock.makeResponseMock>;
|
||||
|
||||
beforeEach(() => {
|
||||
mock = responseMock.makeResponseMock();
|
||||
vi.mocked(NextResponse.next).mockReturnValue(
|
||||
mock as unknown as ReturnType<typeof NextResponse.next>,
|
||||
);
|
||||
});
|
||||
|
||||
it("sets all six security headers on the response", () => {
|
||||
middleware(makeRequest());
|
||||
|
||||
for (const header of ALL_SIX_HEADERS) {
|
||||
expect(mock._store.has(header)).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("does not set a nonce header", () => {
|
||||
middleware(makeRequest());
|
||||
|
||||
expect(mock._store.has("x-nonce")).toBe(false);
|
||||
});
|
||||
|
||||
it("CSP is permissive in development mode", () => {
|
||||
vi.stubEnv("NODE_ENV", "development");
|
||||
|
||||
middleware(makeRequest());
|
||||
|
||||
const csp = mock._store.get("Content-Security-Policy");
|
||||
expect(csp).toContain("'unsafe-inline'");
|
||||
});
|
||||
|
||||
it("CSP uses strict-dynamic in production mode", () => {
|
||||
vi.stubEnv("NODE_ENV", "production");
|
||||
|
||||
middleware(makeRequest());
|
||||
|
||||
const csp = mock._store.get("Content-Security-Policy");
|
||||
expect(csp).toContain("'strict-dynamic'");
|
||||
});
|
||||
});
|
||||
20
apps/cms/src/payload.config.test.ts
Normal file
20
apps/cms/src/payload.config.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import config from "./payload.config";
|
||||
|
||||
describe("CMS app payload.config", () => {
|
||||
it("registers all feature collections", async () => {
|
||||
const resolved = await config;
|
||||
const slugs = resolved.collections?.map((c) => c.slug) ?? [];
|
||||
expect(slugs).toEqual(
|
||||
expect.arrayContaining(["users", "articles", "pages", "media"]),
|
||||
);
|
||||
});
|
||||
|
||||
it("registers all feature globals", async () => {
|
||||
const resolved = await config;
|
||||
const slugs = resolved.globals?.map((g) => g.slug) ?? [];
|
||||
expect(slugs).toEqual(
|
||||
expect.arrayContaining(["site-settings", "header"]),
|
||||
);
|
||||
});
|
||||
});
|
||||
3
apps/cms/src/payload.config.ts
Normal file
3
apps/cms/src/payload.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// Re-export Payload config from @repo/core-cms.
|
||||
// This file exists so @payload-config resolves correctly in the CMS app.
|
||||
export { default } from "@repo/core-cms";
|
||||
Reference in New Issue
Block a user