อ้างอิง › Config
เอกสาร/อ้างอิง/Config

อ้างอิง config

ตัวเลือกทั้งหมดของ easy-cms.config.ts แบ่งตามตำแหน่งที่ใส่ คำอธิบายและตัวอย่างดูได้จากลิงก์ไปยังคู่มือ มีเทสต์ตรวจหน้านี้กับ type ใน @easy-cms/core ทุกตัวเลือกจึงอยู่ในหน้านี้ครบ

import { defineConfig } from '@easy-cms/core'
 
export default defineConfig({ secret, db, collections, /* … */ })

ระดับบนสุด

ตัวเลือกTypeค่าเริ่มต้น
secretstring—จำเป็น อย่างน้อย 32 ตัวอักษร ใช้เซ็น session และ preview token
dbDatabaseAdapter—จำเป็น sqlite() หรือ postgres() ฐานข้อมูล
serverURLstring—origin สาธารณะ (https://example.com) ทำให้ URL ของ media เป็น URL เต็ม
corsstring[] | '*'[]origin ที่โค้ดใน browser เรียก API ได้ ความปลอดภัย
cronSecretstringCRON_SECRETsecret แบบ Bearer สำหรับ GET <api>/jobs/run การตั้งเวลา
webhooksWebhookConfig[][]ดู webhooks
eventsstring[][]event ของแอปหรือ plugin นอกจากการแก้เนื้อหา (<area>.<what> เช่น order.paid) ส่งด้วย cms.emit() ไปยัง webhook ที่ระบุไว้ Webhooks
jobsJobConfig[][]งานที่รันพร้อมงานตั้งเวลา เช่นงานเก็บกวาดของ plugin ดู jobs
localizationLocalizationConfig—ดู localization
routesRoutesConfigดู routes
adminAdminConfigดู admin
uploadUploadConfigดู upload
authAuthConfigดู auth
collectionsCollectionConfig[][]ดู collections
globalsGlobalConfig[][]ดู globals
endpointsEndpoint[][]ดู endpoints
commandsCliCommand[][]คำสั่ง easy-cms <name> เช่นจาก plugin: { name, description, help?, run({ cms, args, log }) } CLI
onRequest({ headers, url, user, cms }) => { context?, user? }—ทำงานทุก request ของ API เมื่อรู้ผู้ใช้แล้ว: คืน context ของ request (เช่น tenant) และเปลี่ยนผู้ใช้ได้ (บทบาทใน tenant นั้น, scoped) ปกติ plugin เป็นผู้ตั้ง Multi-tenant
apiKeysbooleanfalseAPI key ใต้ตั้งค่า สำหรับสคริปต์และแอปอื่น API keys
emailEmailAdapter—ส่งอีเมลให้ plugin เช่น smtp() หรือ consoleEmail() อีเมล
backupsBackupsConfigกดทำเองเท่านั้นbackup ฐานข้อมูลตามรอบ ดู backups
auditboolean | AuditConfigปิดaudit log: ใครแก้อะไร การเข้าสู่ระบบ การจัดการระบบ ดู audit
pluginsPlugin[][](config) => config ทำงานตามลำดับก่อนตรวจ config definePlugin(fn, { name, version }) ตั้งชื่อให้แสดงบนแดชบอร์ด Plugins
fieldTypesFieldTypeDefinition[][]ชนิด field จากแพ็กเกจ เช่น color จาก @easy-cms/fields ชนิด field เพิ่มเติม

routes

ตัวเลือกTypeค่าเริ่มต้น
apistring/api/cmsตำแหน่งของ REST API

admin

ตัวเลือกTypeค่าเริ่มต้น
pathstring/adminตำแหน่งของหน้า admin
locale'en' | 'th'enภาษาเริ่มต้นของหน้า admin ก่อนผู้ใช้เลือกเอง
brandAdminBrand{}ดู brand
siteUrlstring/ (Nuxt, Next.js)เว็บสาธารณะสำหรับปุ่ม "ดูเว็บไซต์": path หรือ URL แบบ http(s)
menustring[]ตามลำดับใน configslug ของ collection ตามลำดับในกลุ่มของเมนู ที่ไม่ระบุจะตามมา
navNavGroup[]—กลุ่มของเมนู: { id, label, icon?, order?, children? } children ลึกได้หนึ่งชั้น มีในตัว: content, settings (site, people, system) ระบบจัดการ
commands{ label, to, icon?, keywords? }[]—รายการเพิ่มเติมใน command palette (⌘K) ที่เปิดหน้าของระบบจัดการ
modulesstring[][]admin module ที่มี Web Components: export ของแพ็กเกจหรือ path Admin components
pagesAdminPage[][]หน้าของตัวเองที่ <admin>/p/<path> เช่น จาก plugin ดู pages
dashboardDashboardWidget[][]กล่องบนแดชบอร์ดต่อจากกล่องที่มีอยู่เดิม ดู dashboard
switcher{ cookie, label, options }—ตัวเลือกด้านบนของเมนูที่ใช้กับทั้ง admin เช่น tenant เก็บใน cookie options คือ path ใต้ API ที่คืน { options: [{ value, label }], all? } ปกติ plugin เป็นผู้ตั้ง

brand

ตัวเลือกType
namestringแสดงในเมนู หน้า login และแท็บของ browser ค่าเริ่มต้น "Easy CMS"
logostringpath บนเว็บของคุณ หรือ URL แบบ https://
colorstringสีหลักแบบ #rrggbb ระบบสร้างเฉดสีให้

pages

ตัวเลือกType
pathstringจำเป็น ตัวพิมพ์เล็ก ตัวเลข และ - ไม่ซ้ำกัน หน้าจะอยู่ที่ <admin>/p/<path>
componentAdminComponentจำเป็น เนื้อหาของหน้า ส่วนหัวหน้า admin วาดให้
labelstring | { en, th }จำเป็น หัวข้อในส่วนหัว เมนู และแท็บของ browser
iconAdminIconไอคอนในเมนู ค่าเริ่มต้น file-text
group'content' | 'settings' | false | stringกลุ่มในเมนู: content, settings, id ของกลุ่ม (admin.nav) หรือ label false คือไม่แสดง ค่าเริ่มต้น content
access({ user }) => booleanใครเปิดได้ ตรวจฝั่ง server ค่าเริ่มต้น: ทุกคนที่ login

dashboard

ตัวเลือกType
componentAdminComponentจำเป็น เนื้อหาของกล่อง
width'half' | 'full'half (ค่าเริ่มต้น): คอลัมน์ข้าง full: ใต้ทั้งสองคอลัมน์ บนมือถือเป็นคอลัมน์เดียว
labelLabelชื่อของกล่องในหน้า Settings → Roles (auth.rbac) ค่าเริ่มต้น: tag ของ component
access({ user }) => booleanใครเห็น ตรวจฝั่ง server ค่าเริ่มต้น: ทุกคนที่ login

วิธีเขียนดูที่ หน้าของ plugin และกล่องบนแดชบอร์ด

backups

ตัวเลือกTypeค่าเริ่มต้น
every'day' | 'week'—backup อัตโนมัติ ถ้าไม่ตั้ง admin กดทำเองได้
atstring03:00เวลา HH:MM ตามเขตเวลาของ server
keepnumber7จำนวน backup ที่สำเร็จที่จะเก็บ ชุดที่เก่ากว่าจะถูกลบ
dirstringbackupsโฟลเดอร์ของที่เก็บในเครื่อง ไม่เปิดเป็น URL สาธารณะ
storageStorageAdapterดิสก์ในเครื่องเช่น s3Storage() กับ bucket ส่วนตัว
sqlite(options) => DatabaseAdapter—เฉพาะ Postgres: sqlite จาก @easy-cms/db-sqlite ใช้เขียนไฟล์ backup Backup

audit

ตัวเลือกTypeค่าเริ่มต้น
keepnumber365เก็บกี่วัน ที่เก่ากว่าจะถูกลบ 0: เก็บไว้ทั้งหมด
valuesbooleantrueเก็บค่าก่อนและหลังการแก้ false: เก็บแค่ชื่อ field ที่เปลี่ยน
failedLoginsnumber20จำนวน login ไม่สำเร็จในหนึ่งชั่วโมงที่แดชบอร์ดจะเตือน Audit log
scope(context) => string | null—ส่วนของเว็บที่ entry เป็นของ เช่น tenant (ปกติ plugin เป็นผู้ตั้ง) admin ของส่วนนั้น (scoped) เห็นเฉพาะของส่วนตัวเอง คนอื่นเห็นของส่วนที่เลือกหรือทั้งหมด

auth

ตัวเลือกTypeค่าเริ่มต้น
rolesstring[]['admin', 'editor']ต้องมี admin เมื่อเปิด rbac คือ role ที่มีอยู่เสมอ ผู้ใช้และการยืนยันตัวตน
rbacbooleanfalseกำหนด role และสิทธิ์จากหน้า admin (Settings → Roles) ซ้อนบนกฎ access บทบาทและสิทธิ์
providersAuthProvider[][]เข้าสู่ระบบหน้า admin ด้วยบัญชีภายนอก เช่น [google()] จาก @easy-cms/auth-oauth Single sign-on
allowSignUp{ domains, role? }—เมื่อมี providers: คนจากโดเมนอีเมลเหล่านี้ได้บัญชีตอนเข้าสู่ระบบครั้งแรก เป็น role (ห้ามเป็น admin)
passwordbooleantruefalse: เฉพาะ admin ที่ใช้รหัสผ่านได้ คนอื่นใช้ providers
setupCodestringEASY_CMS_SETUP_CODEรหัสที่ admin คนแรกต้องกรอกที่ /admin กันคนอื่นแย่งเว็บที่เพิ่ง deploy ถ้าไม่ตั้งจะไม่ถาม Deploy ด้วยคลิกเดียว
tokenExpirationnumber604800 (7 วัน)อายุของ session เป็นวินาที
maxLoginAttemptsnumber5จำนวนครั้งที่ login ผิดได้ต่อ email (และ IP) ภายใน lockWindow
lockWindownumber900 (15 นาที)เป็นวินาที
trustedOriginsstring[][]origin อื่นที่ส่ง request ด้วย cookie ได้
resetPasswordExpirationnumber3600ลิงก์ "ลืมรหัสผ่าน" ใช้ได้กี่วินาที ต้องมี email และ serverURL บน production ลืมรหัสผ่าน
inviteExpirationnumber604800ลิงก์คำเชิญใช้ได้กี่วินาที
emails{ resetPassword?, invite?, passwordChanged? }—ฟังก์ชัน ({ user, url, locale, expiresAt }) => { subject, text, html? } สำหรับข้อความอีเมลของคุณเอง
membersMembersConfig—คนที่ล็อกอินบนหน้าเว็บ ไม่ใช่ระบบจัดการ เช่น ลูกค้า ดู members

members

ตัวเลือกType
rolesstring[]role ของสมาชิก (ต้องอยู่ใน roles ด้วย) สมาชิกเข้าระบบจัดการไม่ได้ และ isLoggedIn (ค่าเริ่มต้นของทุก collection) ไม่นับพวกเขา สมาชิกของเว็บ
signupMembersSignupให้ผู้เยี่ยมชมสมัครบัญชีเองได้: POST <api>/users/signup
pages{ verifyEmail?, resetPassword? }หน้าของเว็บที่เปิดลิงก์ในอีเมลของสมาชิกพร้อม ?token= เป็น path บน admin.siteUrl (หรือ serverURL) หรือ URL เต็ม ค่าเริ่มต้นคือหน้าของระบบจัดการ
emails{ verifyEmail? }ข้อความอีเมลยืนยันที่อยู่อีเมลของคุณเอง

signup

ตัวเลือกTypeค่าเริ่มต้น
rolestring—role ของบัญชีใหม่ ต้องเป็นหนึ่งใน members.roles
verifyEmailbooleantrueบัญชีใหม่ต้องยืนยันอีเมลด้วยลิงก์ก่อนล็อกอิน
turnstile{ siteKey, secretKey }—Cloudflare Turnstile ตรวจทุกครั้งที่สมัคร

upload

ตัวเลือกTypeค่าเริ่มต้น
dirstringuploadsโฟลเดอร์ของที่เก็บไฟล์ในเครื่อง นับจาก root ของโปรเจกต์
maxFileSizenumber10485760 (10 MB)เป็น byte
mimeTypesstring[]['image/*', 'application/pdf']ประเภทไฟล์ที่อนุญาต ตรวจจากเนื้อไฟล์: MIME type, type/* หรือ documents, office, archives ดูชนิดไฟล์
storageStorageAdapterดิสก์ในเครื่องเช่น s3Storage() จาก @easy-cms/storage-s3 อัปโหลด
imageSizesImageSize[][]รูปย่อ (ต้องมี sharp) ดู ขนาดรูป
fromURLUploadFromURLConfigปิดอัปโหลดจากลิงก์ ดู fromURL
privateStorageStorageAdapterstorage ที่ไม่มี URL สาธารณะที่เก็บไฟล์ในโฟลเดอร์ส่วนตัว ดูโฟลเดอร์ส่วนตัว
foldersbooleanfalseโฟลเดอร์ในคลังสื่อ และเมื่อเปิด auth.rbac กำหนดได้ว่าใครใช้แต่ละโฟลเดอร์ ดูโฟลเดอร์

fromURL

ตัวเลือกType
allowedHostsstring[]จำเป็น images.example.com, *.example.com (subdomain) หรือ * (ทุก host สาธารณะ)
allowPrivatebooleanรวมที่อยู่ในเครือข่ายภายใน (localhost, 10.x…) ด้วย ค่าเริ่มต้น false อ่านก่อน

ขนาดรูป

ตัวเลือกTypeค่าเริ่มต้น
namestring—key ใน media.sizes เช่น thumbnail
widthnumber—ความกว้างเป็น pixel
heightnumber—ความสูง (ไม่บังคับ)
fit'cover' | 'contain' | 'inside'coverวิธีจัดรูปเมื่อกำหนดทั้งกว้างและสูง

localization

ตัวเลือกTypeค่าเริ่มต้น
localesstring[]—ภาษาของเนื้อหา เช่น ['th', 'en'] หลายภาษา
defaultLocalestringภาษาแรกใช้เมื่อไม่ระบุภาษา และใช้เติมค่าที่ว่าง
fallbackbooleantrueถ้าค่าว่าง จะอ่านค่าจากภาษาเริ่มต้นแทน

webhooks

ตัวเลือกTypeค่าเริ่มต้น
urlstring—ปลายทางที่จะ POST event Webhooks
eventsstring[]ทั้งหมดcreate, update, delete, publish, unpublish, draft
collectionsstring[]ทั้งหมดcollection ที่ส่ง event ใช้ [] เพื่อไม่ส่งเลย
globalsstring[]ทั้งหมดglobal ที่ส่ง event ใช้ [] เพื่อไม่ส่งเลย
secretstring—เซ็น body: x-easy-cms-signature: sha256=<hex>
headersRecord<string, string>—header เพิ่มเติม

events รับ events ของ config ด้วย (เช่น order.paid) event เหล่านี้ส่งไปเฉพาะ webhook ที่ระบุไว้

jobs

ตัวเลือกType
namestringไม่ซ้ำกัน ตัวพิมพ์เล็ก ใช้ - และ : ได้ เช่น shop:carts
everynumberรันห่างกันอย่างน้อยกี่วินาที เวลาที่รันล่าสุดเก็บในฐานข้อมูล ค่าเริ่มต้น: ทุกรอบ
run({ cms, now }) => unknownงานที่ทำ ถ้าล้มเหลวจะบันทึก log และงานอื่นยังรันต่อ

งานเหล่านี้รันพร้อมงานตั้งเวลา: ทุกนาทีบน server หรือทุกครั้งที่ cron เรียก GET <api>/jobs/run

collections

ตัวเลือกTypeค่าเริ่มต้น
slugstring—จำเป็น URL และชื่อตาราง: ตัวพิมพ์เล็ก ตัวเลข - และ _
fieldsField[]—จำเป็น ดู อ้างอิง field
labels{ singular?, plural? }สร้างจาก slugแต่ละตัวเป็น string หรือ { en, th }
iconAdminIconfile-textไอคอนในเมนู แบรนด์
useAsTitlestring—field ระดับบนสุดที่ใช้เป็นชื่อเอกสาร
editIn'page' | 'drawer'pagedrawer แก้ในแผงที่เลื่อนมาทับรายการ (ใช้ได้เมื่อไม่มี drafts, versions หรือ preview)
draftsbooleanfalseเพิ่ม status (draft | published) ฉบับร่าง
versionsboolean | VersionsConfigfalseเก็บเวอร์ชันทุกครั้งที่บันทึก ดู versions
schedulebooleanfalseเผยแพร่และยกเลิกตามเวลา (ต้องมี drafts)
preview({ doc, locale }) => string | null—หน้าที่แสดงเอกสาร สำหรับตัวอย่างสด
access{ read?, create?, update?, delete? }ต้อง loginการควบคุมสิทธิ์
hooksCollectionHooks—ดู hooks
adminCollectionAdmin—ดู admin components

versions

ตัวเลือกTypeค่าเริ่มต้น
maxnumber50จำนวนเวอร์ชันที่เก็บต่อเอกสาร เวอร์ชันเก่ากว่านั้นจะถูกลบ

hooks

แต่ละตัวเป็น list ของฟังก์ชัน Hooks

Hookอาร์กิวเมนต์ค่าที่คืน
beforeValidatedata, operation, originalDoc?data ใหม่ หรือไม่คืน
beforeChangedata, operation, originalDoc?data ใหม่ หรือไม่คืน
afterChangedoc, operation, previousDoc?—
beforeDeleteid—
afterDeleteid, doc—
afterReaddocdoc ใหม่ หรือไม่คืน

ทุก hook ได้ user, cms และ slug ด้วย

Admin components

ตัวเลือกType
sidebarSidebarPanel[]กล่องในแถบข้างของหน้าแก้ไข { tag, props, position: 'top' } วางไว้บนสุด Admin components
groupstring | Labelกลุ่มในเมนู: id ของกลุ่ม (admin.nav เช่น shop.catalog), settings (ตั้งค่า › เว็บไซต์) หรือ label ซึ่งสร้างกลุ่มชื่อนั้น ค่าเริ่มต้น: เนื้อหา ระบบจัดการ
layoutLayoutNode[]แท็บ ส่วนที่พับได้ และแถวของหน้าแก้ไข ตามชื่อ field ระบบจัดการ
badge{ where, tone?, label? }ตัวเลขข้างรายการในเมนู: เอกสารที่ตรง where ที่ผู้ใช้อ่านได้ เช่น คำสั่งซื้อรอจัดส่ง
countbooleanจำนวนเอกสารข้างรายการในเมนู ค่าเริ่มต้น true
empty{ description?, link? }ข้อความในหน้ารายการเมื่อยังไม่มีเอกสาร และลิงก์ ({ label, href })
list{ tree?, sort? }หน้ารายการ: tree คือชื่อ relationship ไปหา collection เดียวกัน เพื่อแสดงเป็นต้นไม้ (เอกสารระดับบนก่อน เอกสารลูกเปิดอยู่ข้างใต้) ส่วน sort คือลำดับเริ่มต้น เช่น 'title'
ownerFieldstringเมื่อเปิด auth.rbac: relationship ไปที่ users ที่บอกเจ้าของ เช่น 'author' สำหรับบทบาทที่ได้ "เฉพาะเอกสารของตัวเอง" ค่าเริ่มต้น: ผู้สร้าง (createdBy) บทบาทและสิทธิ์
confirmDelete{ typeTitle?, impact? }ถามมากขึ้นก่อนลบ: typeTitle ให้พิมพ์ชื่อ impact คือ path ใต้ API ที่เรียกพร้อม ?id= แล้วคืน { message } บอกสิ่งที่จะหายไปด้วย ลบจากการเลือกหลายรายการไม่ได้

globals

ตัวเลือกTypeค่าเริ่มต้น
slugstring—จำเป็น
fieldsField[]—จำเป็น
labelstring | { en, th }สร้างจาก slug
iconAdminIconsettingsไอคอนในเมนู
draftsbooleanfalse
versionsboolean | VersionsConfigfalse
schedulebooleanfalseต้องมี drafts
preview({ doc, locale }) => string | null—
access{ read?, update? }ต้อง login
scope({ context, user }) => string | null | undefined—เก็บค่าแยกตาม scope เช่นต่อ tenant: string ได้ค่าของตัวเอง undefined ใช้ค่ากลาง null ไม่มี (อ่านได้ค่าว่าง แก้ไม่ได้)
hooksGlobalHooks—ดูด้านล่าง
adminContainerAdmin—{ sidebar } เหมือน collection

Hook ของ global

Hookอาร์กิวเมนต์ค่าที่คืน
beforeChangedata, operation, originalDoc?data ใหม่ หรือไม่คืน
afterChangedoc, operation, previousDoc?—
afterReaddocdoc ใหม่ หรือไม่คืน

endpoints

ตัวเลือกType
pathstringใต้ routes.api เช่น /seo/generate หรือ /stats/:collection
method'get' | 'post' | 'put' | 'patch' | 'delete'
handler(request: EndpointRequest) => unknownคืน Response หรือค่าที่ส่งเป็น JSON Endpoints
rootbooleanเสิร์ฟ path จาก root ของเว็บ (เฉพาะ standalone server) เช่น /robots.txt ค่าเริ่มต้น false

EndpointRequest

PropertyType
requestRequestrequest แบบ Web
urlURLURL ของ request
paramsRecord<string, string>ค่าของ segment แบบ :name
userAuthUser | nullผู้ใช้ที่ login อยู่
contextRequestContextcontext ของ request (onRequest) ส่งต่อให้ Local API พร้อม user
ipstring | undefinedIP ของ client ถ้า adapter รู้
cmsEasyCMSLocal API
json() => Promise<object>body แบบ JSON (ต้องเป็น object ขนาดไม่เกิน 1 MB)