// storage-adapter-import-placeholder import { mongooseAdapter } from '@payloadcms/db-mongodb' import { s3Storage } from '@payloadcms/storage-s3' import { resendAdapter } from '@payloadcms/email-resend' import sharp from 'sharp' // sharp-import import path from 'path' import { buildConfig, PayloadRequest } from 'payload' import { fileURLToPath } from 'url' import { Categories } from './collections/Categories' import { Media } from './collections/Media' import { Pages } from './collections/Pages' import { Posts } from './collections/Posts' import { Users } from './collections/Users' import { Footer } from './Footer/config' import { Header } from './Header/config' import { plugins } from './plugins' import { defaultLexical } from '@/fields/defaultLexical' import { getServerSideURL } from './utilities/getURL' const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) export default buildConfig({ admin: { components: { // The `BeforeLogin` component renders a message that you see while logging into your admin panel. // Feel free to delete this at any time. Simply remove the line below. beforeLogin: ['@/components/BeforeLogin'], // The `BeforeDashboard` component renders the 'welcome' block that you see after logging into your admin panel. // Feel free to delete this at any time. Simply remove the line below. beforeDashboard: ['@/components/BeforeDashboard'], }, importMap: { baseDir: path.resolve(dirname), }, user: Users.slug, livePreview: { breakpoints: [ { label: 'Mobile', name: 'mobile', width: 375, height: 667, }, { label: 'Tablet', name: 'tablet', width: 768, height: 1024, }, { label: 'Desktop', name: 'desktop', width: 1440, height: 900, }, ], }, }, // This config helps us configure global or default features that the other editors can inherit editor: defaultLexical, db: mongooseAdapter({ url: process.env.DATABASE_URI || '', }), collections: [Pages, Posts, Media, Categories, Users], cors: [ getServerSideURL(), 'http://localhost:4321', // Astro dev server 'http://localhost:8788', // Wrangler Pages dev server ].filter(Boolean), globals: [Header, Footer], email: resendAdapter({ defaultFromAddress: 'dev@resend.com', defaultFromName: '恩群數位行銷', apiKey: process.env.RESEND_API_KEY || '', }), plugins: [ ...plugins, s3Storage({ collections: { media: true, }, bucket: process.env.R2_BUCKET!, config: { endpoint: `https://${process.env.R2_ACCOUNT_ID!}.r2.cloudflarestorage.com`, credentials: { accessKeyId: process.env.R2_ACCESS_KEY_ID!, secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!, }, region: 'auto', // ... Other S3 configuration }, }), ], secret: process.env.PAYLOAD_SECRET, sharp, typescript: { outputFile: path.resolve(dirname, 'payload-types.ts'), }, jobs: { access: { run: ({ req }: { req: PayloadRequest }): boolean => { // Allow logged in users to execute this endpoint (default) if (req.user) return true // If there is no logged in user, then check // for the Vercel Cron secret to be present as an // Authorization header: const authHeader = req.headers.get('authorization') return authHeader === `Bearer ${process.env.CRON_SECRET}` }, }, tasks: [], }, })