시드 파일

이 페이지

시드 파일은 EmDash 사이트의 초기 스키마와 선택적 샘플 데이터를 설명합니다. 현재 템플릿은 이를 seed/seed.json에 두고 package.json#emdash.seed로 가리킵니다.

EmDash는 빌드 시 시드를 임베드합니다. 최초 설정과 명시적 시드 명령용이며, 배포마다 실행되는 마이그레이션이 아닙니다.

파일 검색

Astro 통합은 다음 순서로 시드를 찾습니다.

  1. .emdash/seed.json.
  2. package.json#emdash.seed의 경로.
  3. seed/seed.json.
  4. 사용자 시드가 없을 때의 내장 기본 시드.

다음 패키지 필드는 템플릿의 관례 경로를 선택합니다.

{
  "emdash": {
    "seed": "seed/seed.json"
  }
}

루트 형태

다음 예시에는 모든 루트 속성이 들어 있습니다.

{
  "$schema": "https://emdashcms.com/seed.schema.json",
  "version": "1",
  "defaultLocale": "en",
  "meta": {
    "name": "Publication",
    "description": "A publication seed",
    "author": "Example Studio"
  },
  "settings": {},
  "blockTypes": [],
  "collections": [],
  "relations": [],
  "taxonomies": [],
  "bylines": [],
  "content": {},
  "menus": [],
  "redirects": [],
  "widgetAreas": [],
  "sections": []
}
속성필수용도
$schema아니요에디터용 스키마 URL
version예시드 형식. 허용 값은 "1"뿐
defaultLocale아니요locale을 생략한 로케일 행의 로케일. 기본값은 런타임 설정, 그다음 en
meta아니요설정 중 표시되는 설명 이름, 설명, 작성자
settings아니요부분 사이트 설정
blockTypes아니요blocks 필드가 쓰는 버전 지정 정의
collections아니요컬렉션 및 필드 정의
taxonomies아니요택소노미 정의와 선택적 용어
bylines아니요선택적 표시 크레딧 프로필
content아니요컬렉션 슬러그별로 그룹화된 샘플 항목
menus아니요메뉴와 중첩 항목
redirects아니요로컬 리다이렉트 규칙
widgetAreas아니요위젯 영역과 위젯
sections아니요재사용 가능한 Portable Text 섹션

defaultLocale은 앞뒤 공백이 없는 비어 있지 않은 문자열이어야 합니다.

설정

settings는 사이트 설정의 일부를 담는 객체입니다. 일반적인 속성은 title, tagline, logo, favicon, url, postsPerPage, dateFormat, timezone, social, seo입니다.

설정 마법사에서는 관리자가 시드된 제목과 태그라인을 바꿀 수 있습니다. 기본값인 onConflict: "skip"은 시드를 다시 적용할 때 그 값을 유지하고, 제공된 설정 중 아직 없는 것을 채웁니다.

{
  "version": "1",
  "settings": {
    "title": "Field Notes",
    "tagline": "Reports from the team",
    "postsPerPage": 12,
    "dateFormat": "MMMM d, yyyy",
    "timezone": "Europe/London"
  }
}

블록 타입

blockTypes는 blocks 컬렉션 필드가 쓰는 버전 지정 형태를 정의합니다. EmDash는 이 정의를 컬렉션보다 먼저 적용하므로, 필드는 validation.allowedTypes에서 이를 지정할 수 있습니다.

다음 시드는 저장된 콘텐츠와 리비전을 위해 버전 1을 유지하면서, 새 블록에는 버전 2를 활성 버전으로 사용합니다.

{
  "version": "1",
  "blockTypes": [
    {
      "slug": "hero",
      "label": "Hero",
      "category": "Layout",
      "currentVersion": 2,
      "versions": [
        {
          "version": 1,
          "fields": [
            { "slug": "heading", "label": "Heading", "type": "string", "required": true }
          ]
        },
        {
          "version": 2,
          "fields": [
            { "slug": "title", "label": "Title", "type": "string", "required": true },
            { "slug": "image", "label": "Image", "type": "image" }
          ]
        }
      ]
    }
  ],
  "collections": [
    {
      "slug": "pages",
      "label": "Pages",
      "fields": [
        {
          "slug": "layout",
          "label": "Layout",
          "type": "blocks",
          "validation": { "allowedTypes": ["hero"], "maxItems": 20 }
        }
      ]
    }
  ]
}

버전 번호는 1부터 시작하는 연속된 양의 정수입니다. currentVersion은 선언된 버전 중 하나를 지정해야 합니다. 시드를 내보내고 다시 적용해도 정확한 버전 번호와 활성 버전 포인터가 그대로 유지되며, EmDash는 번호를 다시 매기지 않습니다.

onConflict: "update"에서는 새 정의가 호환될 때만 시드가 저장된 버전을 수정할 수 있습니다. 호환되지 않는 정의로 기존 번호를 재사용하면 BLOCK_TYPE_VERSION_CONFLICT로 실패합니다. 호환성을 깨는 정의에는 새 버전 번호를 추가하세요.

저장된 블록 값에는 _type, _version, _key가 들어 있습니다. 시드 콘텐츠가 유지된 버전을 대상으로 할 때는 이 속성들을 제공하세요. 새로 기록되는 블록이 이를 생략하면 런타임이 활성 버전과 키를 할당합니다.

컬렉션

컬렉션에는 slug, label, fields가 필요합니다.

{
  "version": "1",
  "collections": [
    {
      "slug": "posts",
      "label": "Posts",
      "labelSingular": "Post",
      "description": "Published articles",
      "supports": ["drafts", "revisions", "scheduling", "search", "seo"],
      "urlPattern": "/posts/{slug}",
      "routable": true,
      "commentsEnabled": true,
      "editLocking": true,
      "titleField": "title",
      "dateField": "event_date",
      "admin": {
        "listColumns": ["event_date"]
      },
      "fields": [
        { "slug": "title", "label": "Title", "type": "string", "required": true },
        { "slug": "event_date", "label": "Event date", "type": "datetime", "indexed": true },
        { "slug": "content", "label": "Content", "type": "portableText" }
      ]
    }
  ]
}

컬렉션 속성

속성타입동작
slugstring필수 데이터베이스 및 API 이름. 소문자로 시작하며 소문자, 숫자, 밑줄을 포함
labelstring필수 복수형 UI 레이블
labelSingularstring선택적 단수형 UI 레이블
descriptionstring선택적 관리자 설명
iconstring사이드바 항목에 쓰는 Phosphor 아이콘 이름. 예: calendar-blank
admin.listColumnsstring[]콘텐츠 목록에 표시할, 선언된 필드 슬러그 최대 4개
admin.quickCreateboolean대시보드에 이 컬렉션의 “새 항목” 빠른 작업을 표시할지 여부. 기본값 true
supportsstring[]drafts, revisions, preview, scheduling, search, seo 중 아무 것
urlPatternstring/posts/{slug} 같은 공개 패턴. 경로 세그먼트당 자리 표시자는 최대 1개
routableboolean게시된 항목에 슬러그가 필요한지 여부. 기본값 true
hiddenboolean생성된 사이드바 링크, 명령 팔레트 링크, 대시보드 빠른 작업을 숨김. 컬렉션은 URL과 API로는 계속 접근 가능
sortOrdernumber관리자 사이드바의 명시적 위치. 순서가 지정된 컬렉션이 먼저, 오름차순으로 옴
groupstring관리자 사이드바 폴더. 같은 그룹의 컬렉션은 접을 수 있는 하나의 항목을 공유
commentsEnabledboolean컬렉션의 댓글을 활성화
editLockingboolean편집 잠금을 활성화. 기본값 true
titleFieldstring콘텐츠 목록 제목에 쓰는 필드
dateFieldstring콘텐츠 목록 날짜에 쓰는 datetime 필드
fieldsSeedField[]필수 필드 정의

sortOrder는 컬렉션에 속하며 사이드바 순서를 제어합니다. SeedField에는 sortOrder 속성이 없습니다. 필드는 배열 순서대로 생성됩니다.

필드 속성

속성타입용도
slugstring컬렉션 슬러그와 같은 패턴을 쓰는 필수 필드 이름
labelstring필수 UI 레이블
typeFieldType필수 저장 필드 타입
requiredboolean비어 있는 필수 값을 거부
uniqueboolean고유성 제약을 추가
searchableboolean컬렉션 검색에 필드를 포함
indexedboolean지원되는 스칼라 타입에 쿼리 인덱스를 추가
translatableboolean로케일마다 값을 저장. 기본값 true. false는 번역 간에 값 하나를 공유
defaultValue임의필드를 생략했을 때의 초기 값
validation객체생성된 콘텐츠 스키마가 쓰는 검증 규칙
widgetstring관리자 필드 위젯 재정의
options객체위젯별 옵션

지원되는 필드 타입은 다음과 같습니다.

  • string, text, url, slug.
  • number, integer, boolean.
  • datetime.
  • select, multiSelect.
  • portableText, json, repeater.
  • blocks.
  • image, file, reference.

reference 필드는 컬렉션 테이블에 아무것도 저장하지 않습니다. 링크는 연결된 관계에 있습니다. 관계를 참고하세요.

indexed: true를 설정할 수 있는 것은 string, url, number, integer, boolean, datetime, select, reference, slug뿐입니다. reference 필드에서는 필드에 관계가 없는 동안에만 이 플래그가 적용됩니다. 연결된 필드에는 인덱스를 만들 열이 없기 때문입니다.

필드 검증

생성된 컬렉션 스키마는 필드 타입이 지원하는 곳에서 다음 규칙을 인식합니다.

규칙사용처
min, max숫자 필드
minLength, maxLength, pattern문자열 형태 필드
optionsselect 및 multiSelect
subFields, minItems, maxItemsrepeater
allowedTypes, minItems, maxItemsblocks
allowedMimeTypes미디어 필드

blocks 필드의 retiredTypes는 서버가 관리합니다. allowedTypes에서 슬러그를 제거하면 해당 타입이 폐기 처리되어, 저장된 기존 블록은 유효한 채로 남지만 새 블록은 쓸 수 없습니다.

validateSeed()는 validation이나 options의 모든 규칙을 깊이 타입 검사하지는 않습니다. 따라서 잘못된 규칙이 시드 검증을 통과한 뒤, 나중에 컬렉션 스키마를 만들거나 콘텐츠를 기록할 때 실패할 수 있습니다.

관계

관계는 두 컬렉션을 묶고 그 항목 간 링크를 소유합니다. reference 필드는 관계 하나에 연결되어 한쪽 끝에서 그 링크를 봅니다. 다음 시드는 게시물당 저자 한 명을 허용하는 posts와 authors 사이의 관계를 선언합니다.

{
	"relations": [
		{
			"slug": "post_authors",
			"parentCollection": "posts",
			"childCollection": "authors",
			"parentLabel": "Posts",
			"parentLabelSingular": "Post",
			"childLabel": "Authors",
			"childLabelSingular": "Author",
			"maxChildrenPerParent": 1
		}
	]
}
속성타입필수설명
slugstring예reference 필드가 관계를 가리킬 때 쓰는 고유 이름
parentCollectionstring예부모 쪽 컬렉션
childCollectionstring예자식 쪽 컬렉션
parentLabelstring예자식에서 본 부모 역할 이름
parentLabelSingularstring아니요parentLabel의 단수형
childLabelstring예부모에서 본 자식 역할 이름
childLabelSingularstring아니요childLabel의 단수형
maxChildrenPerParentnumber | null아니요부모가 연결할 수 있는 자식 수(null: 제한 없음)
maxParentsPerChildnumber | null아니요자식이 연결할 수 있는 부모 수(null: 제한 없음)

collections의 reference 필드는 연결할 관계를 지정합니다.

{
	"slug": "author",
	"label": "Author",
	"type": "reference",
	"validation": { "relation": "post_authors" }
}

필드는 대신 targetCollection을 지정하고 그에 대한 관계를 만들게 할 수도 있습니다. 이는 한쪽 컬렉션만 보는 링크에 가장 짧은 경로입니다. 양쪽 컬렉션이 봐야 하거나 레이블과 한도를 설정하려면 relations에서 관계를 선언하세요. reference는 두 형태와 각 형태가 받는 검증 키를 설명합니다.

관계의 두 컬렉션은 한 번 만들어지면 고정됩니다. 다른 컬렉션을 지정하는 시드는, 관계가 보유한 링크가 더 이상 관계의 끝이 아닌 컬렉션을 가리키게 되는 일이 없도록 실패합니다. 레이블과 한도는 시드가 onConflict: "update"로 적용될 때 업데이트됩니다.

택소노미

택소노미 정의는 대상 컬렉션을 식별합니다. 용어는 샘플 데이터이며 includeContent가 true일 때만 적용됩니다.

{
  "version": "1",
  "taxonomies": [
    {
      "name": "category",
      "label": "Categories",
      "labelSingular": "Category",
      "hierarchical": true,
      "collections": ["posts"],
      "terms": [
        { "slug": "engineering", "label": "Engineering" },
        { "slug": "platform", "label": "Platform", "parent": "engineering" }
      ]
    }
  ]
}

택소노미는 시드 로컬 id, locale, translationOf를 가질 수 있습니다. 용어도 이 속성들을 가질 수 있습니다. translationOf는 다른 시드 로컬 ID를 가리킵니다. 용어는 번역 원본 용어 뒤에 와야 합니다. 같은 name의 택소노미 항목은 어떤 순서로든 나올 수 있습니다. 택소노미의 구조를 선언하는 항목이 번역보다 먼저 적용되기 때문입니다.

hierarchical과 collections는 택소노미의 모든 로케일이 공유하므로, translationOf가 같은 name의 항목을 가리키는 택소노미 항목은 이를 생략할 수 있습니다. 적용 엔진은 같은 name의 항목을 따라 translationOf를 추적하고 마지막 항목에서 값을 가져옵니다. 번역이 가져오는 값과 다른 값을 선언하거나, 한 택소노미에 대해 이를 선언한 두 항목이 서로 다르면 검증이 경고합니다. 기존 택소노미는 translationOf가 없는 항목이 대체하지 않는 한 값을 유지합니다. 이는 onConflict: "update"에서 일어나며, 항목의 로케일에 충돌 동작에서 설명하는 수정되지 않은 내장 category 또는 tag 정의가 있거나 그 내장 정의가 택소노미의 유일한 정의인 경우에는 모든 모드에서 일어납니다. 내보내기는 번역이 가리키는 항목에만 이를 기록합니다.

용어의 parent는 같은 로케일에 있는 부모 용어의 슬러그입니다. 비계층 택소노미의 parent는 경고를 내고 무시됩니다. translationOf가 있고 parent가 없는 용어는 번역 원본 용어의 parent를 따릅니다.

바이라인

루트의 bylines는 표시 크레딧을 정의합니다. 샘플 데이터이며 includeContent: true가 필요합니다.

{
  "version": "1",
  "bylines": [
    {
      "id": "byline-editor",
      "slug": "alex-editor",
      "displayName": "Alex Editor",
      "isGuest": true
    }
  ]
}

id는 시드 로컬이며 콘텐츠 크레딧이 사용합니다. 선택적 속성은 bio, websiteUrl, isGuest, avatar입니다.

바이라인 아바타는 설정된 스토리지에 이미 있는 파일을 가리킵니다.

{
  "id": "byline-editor",
  "slug": "alex-editor",
  "displayName": "Alex Editor",
  "avatar": {
    "storageKey": "avatars/alex.jpg",
    "filename": "alex.jpg",
    "mimeType": "image/jpeg",
    "alt": "Alex Editor",
    "width": 400,
    "height": 400
  }
}

바이라인 아바타 시딩은 스토리지 키에 대한 미디어 행을 만들거나 재사용합니다. 파일을 업로드하거나 다운로드하지는 않습니다.

콘텐츠

content는 항목을 컬렉션 슬러그별로 그룹화합니다. 각 항목에는 시드 로컬 id와 data 객체가 필요합니다. 라우팅 가능한 컬렉션에는 비어 있지 않은 slug도 필요합니다.

{
  "version": "1",
  "content": {
    "posts": [
      {
        "id": "post-welcome",
        "slug": "welcome",
        "status": "published",
        "data": {
          "title": "Welcome",
          "content": []
        },
        "taxonomies": {
          "category": ["engineering"]
        },
        "bylines": [
          { "byline": "byline-editor", "roleLabel": "Editor" }
        ]
      }
    ]
  }
}
속성필수동작
id예시드 로컬 참조 ID
slug라우팅 가능한 컬렉션에서 필수공개 슬러그이자 충돌 키
status아니요published 또는 draft. 기본값 published
data예컬렉션 필드 슬러그를 키로 하는 값
taxonomies아니요택소노미 이름에서 용어 슬러그 배열로의 매핑
bylines아니요루트 바이라인 ID를 참조하는 순서 있는 크레딧
locale아니요BCP 47 로케일. defaultLocale을 통해 기본값이 정해짐
translationOf아니요같은 컬렉션의 시드 로컬 콘텐츠 ID

라우팅 가능한 항목에서 시드 로컬 id는 데이터베이스 ID가 아닙니다. EmDash가 데이터베이스 ID를 만들고 이후 참조를 위해 매핑을 기록합니다. routable: false인 컬렉션에서 슬러그가 없는 항목은 EmDash가 시드 id를 저장 ID로 사용하므로 다시 적용해도 멱등성이 유지됩니다.

읽을 때 entry.id는 Astro 라우트 식별자이며 보통 슬러그입니다. 저장된 데이터베이스 ID는 entry.data.id입니다.

콘텐츠 참조

data 안에서 $ref: 문자열을 사용하면 시드 로컬 콘텐츠 ID를 생성된 데이터베이스 ID로 바꿉니다.

{
  "id": "event-opening",
  "slug": "opening-night",
  "data": {
    "title": "Opening night",
    "venue": "$ref:venue-main-hall"
  }
}

참조 대상은 적용 엔진의 ID 맵에 존재하도록 충분히 앞에 나와야 합니다. 해석되지 않은 $ref: 값은 원래의 리터럴 문자열로 남으며, validateSeed()는 이를 거부하지 않습니다.

reference 필드의 경우 관계의 부모 쪽에서 링크를 선언하세요. 양쪽 끝이 같은 링크 집합을 보므로, 자식 컬렉션의 필드는 부모가 이미 가진 링크를 중복해서 기술하게 됩니다.

미디어 참조

콘텐츠 데이터에서 $media를 사용하면 URL을 다운로드하고, 제공된 스토리지 어댑터로 업로드하고, 미디어 행을 만든 뒤, 해당 객체를 미디어 필드 값으로 바꿉니다.

{
  "featured_image": {
    "$media": {
      "url": "https://example.com/images/launch.jpg",
      "filename": "launch.jpg",
      "alt": "A product launch on stage",
      "caption": "Launch event"
    }
  }
}

Portable Text의 image 블록이나 gallery 이미지에서 asset 안의 $media는 미디어 참조(_type: "reference", _ref, url, provider)가 되며, 이미지 자체의 alt, width, height가 없으면 미디어의 대체 텍스트와 크기로 채워집니다.

한 번의 적용 호출 안에서는 같은 URL에 대한 반복 참조가 이미 해석된 미디어 값을 재사용합니다. 시드 미디어 참조는 로컬 file 속성을 받지 않습니다. mediaBasePath는 공개 SeedApplyOptions 타입에 남아 있지만 현재 적용 엔진은 이를 읽지 않습니다.

스토리지 어댑터가 제공되지 않으면 $media 참조는 건너뛰고 null로 해석됩니다. skipMediaDownload: true에서는 외부 미디어 값이 되며 스토리지 어댑터가 필요 없습니다.

메뉴

메뉴는 구조 데이터이며 includeContent가 false여도 적용됩니다.

{
  "version": "1",
  "menus": [
    {
      "name": "primary",
      "label": "Primary navigation",
      "items": [
        {
          "type": "page",
          "label": "About",
          "ref": "page-about",
          "collection": "pages"
        },
        {
          "type": "custom",
          "label": "Contact",
          "url": "/contact",
          "target": "_self"
        }
      ]
    }
  ]
}

허용되는 항목 타입은 custom, page, post, taxonomy, collection입니다. custom에는 url이, page와 post에는 ref가 필요합니다. 항목에는 id, translationOf, label, collection, titleAttr, cssClasses, locale, target, 중첩된 children을 포함할 수 있습니다.

page와 post에서 ref는 시드 콘텐츠 ID를 지정합니다. 대상이 없으면 검증 경고가 발생하고, 해석된 콘텐츠 참조가 없는 메뉴 항목이 만들어집니다. 기존 메뉴 항목은 해당 메뉴가 적용될 때마다 onConflict와 관계없이 삭제되고 다시 만들어집니다.

리다이렉트

리다이렉트에는 로컬 소스 경로와 대상 경로가 필요합니다.

{
  "version": "1",
  "redirects": [
    {
      "source": "/old-path",
      "destination": "/new-path",
      "type": 308,
      "enabled": true,
      "groupName": "WordPress migration"
    }
  ]
}

두 경로 모두 / 하나로 시작해야 합니다. 프로토콜 상대 URL, 경로 탐색 세그먼트, 줄바꿈은 거부됩니다. 허용되는 상태 코드는 301, 302, 307, 308입니다.

위젯 영역

위젯 영역에는 content, menu, component 위젯이 들어갈 수 있습니다.

{
  "version": "1",
  "widgetAreas": [
    {
      "name": "sidebar",
      "label": "Sidebar",
      "widgets": [
        {
          "type": "menu",
          "title": "Explore",
          "menuName": "primary"
        },
        {
          "type": "component",
          "title": "Recent posts",
          "componentId": "core:recent-posts",
          "props": { "count": 5 }
        }
      ]
    }
  ]
}

content 위젯은 content에 Portable Text를 저장합니다. menu 위젯에는 menuName이 필요합니다. component 위젯에는 componentId가 필요하며 props를 전달할 수 있습니다. SeedWidget에는 settings 속성이 없습니다.

영역에 있는 기존 위젯은 해당 영역이 적용될 때마다 onConflict와 관계없이 삭제되고 다시 만들어집니다.

Sections

섹션은 재사용 가능한 Portable Text 콘텐츠를 담습니다.

{
  "version": "1",
  "sections": [
    {
      "slug": "newsletter-signup",
      "title": "Newsletter signup",
      "description": "Signup call to action",
      "keywords": ["newsletter", "email"],
      "source": "theme",
      "content": []
    }
  ]
}

섹션 슬러그에는 소문자, 숫자, 하이픈을 쓸 수 있습니다. source는 theme, user, import 중 하나이며, 시드에서는 기본값이 theme입니다. 테마 섹션은 관리자 화면에서 삭제할 수 없습니다. 섹션은 구조 데이터이며 includeContent가 false여도 적용됩니다.

로컬라이제이션

defaultLocale은 택소노미, 용어, 메뉴, 메뉴 항목, 콘텐츠에서 빠진 로케일을 채웁니다. 활성 런타임 i18n 설정이 있으면 그것이 우선합니다.

로컬라이즈된 택소노미, 용어, 메뉴, 메뉴 항목, 콘텐츠는 시드 로컬 id와 translationOf 필드를 사용합니다. 적용 엔진이 번역 그룹을 해석할 수 있도록 번역보다 앞에 원본 항목을 두세요. 번역된 콘텐츠 항목은 locale을 설정해야 하며, 그 translationOf는 같은 컬렉션의 다른 항목을 지정해야 합니다.

프로그래밍 방식 시드 적용

applySeed()와 validateSeed()는 emdash/seed에서 내보냅니다. 다음 헬퍼는 적용하기 전에 검증합니다.

import {
  applySeed,
  validateSeed,
  type SeedApplyOptions,
  type SeedFile,
} from "emdash/seed";

type SeedDatabase = Parameters<typeof applySeed>[0];

export async function applyProjectSeed(
  db: SeedDatabase,
  seed: SeedFile,
  options: SeedApplyOptions,
) {
  const validation = validateSeed(seed);
  if (!validation.valid) {
    throw new Error(validation.errors.join("\n"));
  }

  return applySeed(db, seed, options);
}

SeedApplyOptions

옵션기본값현재 동작
includeContentfalse콘텐츠 항목, 바이라인, 택소노미 용어를 포함
onConflict"skip"지원되는 엔터티 충돌에 대한 "skip", "update", "error"
storage없음$media URL을 다운로드하는 데 필요한 스토리지 어댑터
skipMediaDownloadfalse$media URL을 외부 미디어 값으로 유지
mediaBasePath없음공개 타입에는 있지만 현재 적용 엔진에서는 쓰이지 않음

프로그래밍 방식으로 적용할 때 includeContent의 기본값은 false입니다. 설정 마법사는 관리자의 샘플 콘텐츠 선택을 전달합니다. emdash seed CLI는 --no-content를 지정하지 않으면 기본적으로 콘텐츠를 포함합니다.

충돌 동작

onConflict는 시드 전체에 대한 트랜잭션 정책이 아닙니다.

  • 컬렉션, 필드, 바이라인, 콘텐츠, 리다이렉트, 섹션은 건너뛰기, 업데이트, 오류 동작을 지원합니다.
  • 택소노미 정의와 용어는 해당하는 충돌 모드를 따릅니다. 예외는 모든 새 데이터베이스가 처음부터 가지고 있는 내장 category와 tag 정의입니다. 사이트가 편집하기 전까지는 이를 선언한 시드가 모든 모드에서 해당 정의를 대체합니다.
  • 설정은 키별로 충돌을 처리합니다. skip은 없는 설정을 만들고 기존 값을 유지합니다. update는 제공된 모든 설정을 덮어씁니다. 다만 seo와 social은 제공된 필드만 덮어씁니다. error는 처음 만난 기존 설정에서 멈추며, 시드 순서상 그보다 먼저 만들어진 설정은 적용된 채로 남습니다.
  • 기존 메뉴는 메뉴 행을 유지하지만 모든 항목을 대체합니다.
  • 기존 위젯 영역은 영역 행을 유지하지만 모든 위젯을 대체합니다.
  • 콘텐츠 충돌은 컬렉션, 슬러그, 로케일로 매칭합니다. 라우팅할 수 없는 컬렉션에서 슬러그가 없는 항목은 시드 ID로 매칭합니다.

onConflict: "update"에서는 콘텐츠 데이터가 대체되고, 바이라인 및 택소노미 할당이 시드에 맞게 조정됩니다. 기존 사이트에 사용하기 전에 복사본에서 update 모드를 테스트하세요.

applySeed()는 컬렉션, 필드, 택소노미, 바이라인, 메뉴, 리다이렉트, 위젯 영역, 섹션, 설정, 콘텐츠, 미디어에 대한 카운터를 반환합니다.

검증 동작

validateSeed()는 { valid, errors, warnings }를 반환합니다. applySeed()는 이를 호출하며, 오류가 있으면 Invalid seed file을 던집니다.

검증기는 적용 엔진에 필요한 다음과 같은 구조 규칙을 확인합니다.

  • 버전과 비어 있지 않은 defaultLocale.
  • 컬렉션, 필드, 택소노미, 용어, 메뉴, 위젯 영역, 섹션, 바이라인, 콘텐츠 컨테이너의 형태.
  • 필수 이름, 레이블, ID, 슬러그, 지원되는 필드 또는 위젯 타입.
  • 해당 범위 안에서의 중복 식별자.
  • 인덱싱 가능한 필드 타입과 admin.listColumns 참조.
  • 택소노미 부모, 콘텐츠 번역, 콘텐츠 바이라인 참조, 메뉴 항목 요구 사항.
  • 안전한 로컬 리다이렉트 경로와 상태 코드.

일부 조건은 오류가 아니라 경고입니다. 예를 들어 컬렉션이 없는 택소노미, 평면 택소노미의 parent, 시드에 없는 메뉴 콘텐츠 참조가 있습니다.

검증기는 모든 data 값이 컬렉션 필드에 맞는지 보장하지 않습니다. 또한 사이트 설정, 필드 validation, 필드 options, 임의의 Portable Text 블록, component 위젯 props, 콘텐츠 데이터의 $ref: 대상, 원격 $media의 사용 가능 여부도 깊이 검증하지 않습니다. 유효한 시드도 스키마 생성, 콘텐츠 검증, 네트워크 다운로드, 스토리지 업로드 중에 실패할 수 있습니다.

에디터 지원에는 $schema URL을 사용하고, 적용하기 전에 실행 가능한 검증기를 실행하세요.

npx emdash seed seed/seed.json --validate

CLI 명령

충돌 동작을 명시하여 시드를 로컬 SQLite 데이터베이스에 적용합니다.

npx emdash seed seed/seed.json --database ./data.db --on-conflict skip

현재 로컬 모델과 모든 콘텐츠를 템플릿 경로로 다시 내보냅니다.

npx emdash export-seed --database ./data.db --with-content=all > seed/seed.json

export-seed는 로컬 SQLite 파일에서 직접 동작합니다. 배포된 D1 데이터베이스는 먼저 로컬 파일로 내보내세요. 결과를 커밋하기 전에 내보낸 설정, 콘텐츠, 미디어 참조를 검토하세요. 내보낸 미디어를 다른 사이트에서 가져올 수 있게 하려면 --media-base-url을 전달하세요. 미디어 URL을 참고하세요.

다음 단계

  • 테마 만들기에서 재사용 가능한 Astro 템플릿에 시드를 사용하는 방법을 확인하세요.
  • 스키마 진화에서 이미 배포된 사이트의 모델을 업데이트하는 방법을 확인하세요.
  • CLI 레퍼런스에서 데이터베이스와 내보내기 옵션을 확인하세요.