Arquivos seed

Nesta página

Um arquivo seed descreve o modelo inicial e os dados de exemplo opcionais de um site EmDash. Os templates atuais o armazenam em seed/seed.json e apontam para ele com package.json#emdash.seed.

O EmDash incorpora o seed em tempo de build. Ele é pensado para a primeira configuração e para comandos seed explícitos, não como uma migração executada a cada deploy.

Descoberta do arquivo

A integração do Astro procura um seed nesta ordem:

  1. .emdash/seed.json.
  2. O caminho em package.json#emdash.seed.
  3. seed/seed.json.
  4. O seed padrão integrado quando não existe nenhum seed do usuário.

O campo de pacote a seguir seleciona o caminho convencional do template:

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

Forma raiz

O exemplo a seguir contém todas as propriedades raiz:

{
  "$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": []
}
PropriedadeObrigatóriaFinalidade
$schemaNãoURL do schema para o editor
versionSimFormato do seed; o único valor aceito é "1"
defaultLocaleNãoLocale para as linhas com locale que omitem locale; o padrão é a configuração de runtime e depois en
metaNãoNome descritivo, descrição e autor exibidos durante a configuração
settingsNãoConfigurações parciais do site
blockTypesNãoDefinições versionadas usadas pelos campos blocks
collectionsNãoDefinições de collections e campos
taxonomiesNãoDefinições de taxonomias e termos opcionais
bylinesNãoPerfis opcionais de créditos de apresentação
contentNãoEntradas de exemplo agrupadas por slug da collection
menusNãoMenus e itens aninhados
redirectsNãoRegras de redirecionamento locais
widgetAreasNãoÁreas de widgets e widgets
sectionsNãoSections reutilizáveis de Portable Text

defaultLocale deve ser uma string não vazia, sem espaços no início ou no fim.

Configurações

settings é um objeto parcial de configurações do site. As propriedades comuns são title, tagline, logo, favicon, url, postsPerPage, dateFormat, timezone, social e seo.

O assistente de configuração permite que o administrador substitua o título e o slogan semeados. O padrão onConflict: "skip" preserva esses valores quando o seed é aplicado novamente e preenche as configurações fornecidas que ainda estiverem faltando.

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

Tipos de bloco

blockTypes define as formas versionadas usadas pelos campos de collection blocks. O EmDash aplica essas definições antes das collections, de modo que um campo pode nomeá-las em validation.allowedTypes.

O seed a seguir mantém a versão 1 para o conteúdo e as revisões armazenados, tornando a versão 2 ativa para os novos blocos:

{
  "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 }
        }
      ]
    }
  ]
}

Os números de versão são inteiros positivos contíguos que começam em 1. currentVersion deve nomear uma versão declarada. Exportar e reaplicar um seed preserva os números de versão exatos e o ponteiro da versão ativa; o EmDash não os renumera.

Com onConflict: "update", um seed só pode alterar uma versão armazenada quando a nova definição é compatível. Reutilizar um número existente para uma definição incompatível falha com BLOCK_TYPE_VERSION_CONFLICT. Adicione um novo número de versão para uma definição que quebre a compatibilidade.

Os valores de bloco armazenados incluem _type, _version e _key. Forneça essas propriedades quando o conteúdo do seed apontar para uma versão mantida. O runtime atribui a versão ativa e uma chave quando um bloco recém-escrito as omite.

Collections

Uma collection exige slug, label e 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" }
      ]
    }
  ]
}

Propriedades da collection

PropriedadeTipoComportamento
slugstringNome obrigatório de banco de dados e API; começa com uma letra minúscula e contém letras minúsculas, dígitos e sublinhados
labelstringRótulo de UI obrigatório no plural
labelSingularstringRótulo de UI opcional no singular
descriptionstringDescrição opcional na administração
iconstringNome do ícone Phosphor para a entrada da barra lateral, como calendar-blank
admin.listColumnsstring[]Até quatro slugs de campos declarados exibidos na lista de conteúdo
admin.quickCreatebooleanSe o painel exibe uma ação rápida “Nova entrada” para esta collection; o padrão é true
supportsstring[]Qualquer um entre drafts, revisions, preview, scheduling, search e seo
urlPatternstringPadrão público como /posts/{slug}, com no máximo um marcador de posição por segmento de caminho
routablebooleanSe as entradas publicadas exigem um slug; o padrão é true
hiddenbooleanOculta o link gerado na barra lateral, o link da paleta de comandos e a ação rápida do painel; a collection continua acessível por URL e API
sortOrdernumberPosição explícita na barra lateral da administração; as collections ordenadas vêm primeiro, em ordem crescente
groupstringPasta da barra lateral da administração; as collections com o mesmo grupo compartilham uma entrada recolhível
commentsEnabledbooleanAtiva os comentários para a collection
editLockingbooleanAtiva os bloqueios de edição; o padrão é true
titleFieldstringCampo usado para o título na lista de conteúdo
dateFieldstringCampo datetime usado para a data na lista de conteúdo
fieldsSeedField[]Definições de campo obrigatórias

sortOrder pertence à collection e controla a ordem da barra lateral. SeedField não tem a propriedade sortOrder. Os campos são criados na ordem do seu array.

Propriedades do campo

PropriedadeTipoFinalidade
slugstringNome de campo obrigatório que segue o padrão do slug da collection
labelstringRótulo de UI obrigatório
typeFieldTypeTipo de campo armazenado obrigatório
requiredbooleanRejeita um valor obrigatório vazio
uniquebooleanAdiciona uma restrição de unicidade
searchablebooleanInclui o campo na busca da collection
indexedbooleanAdiciona um índice de consulta para os tipos escalares suportados
translatablebooleanArmazena um valor por locale; o padrão é true. false compartilha um único valor entre as traduções
defaultValuequalquerValor inicial quando o campo é omitido
validationobjetoRegras de validação usadas pelos schemas de conteúdo gerados
widgetstringSubstituição do widget do campo na administração
optionsobjetoOpções específicas do widget

Os tipos de campo suportados são:

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

Um campo reference não armazena nada na tabela da collection. Seus links ficam na relação à qual ele está vinculado; consulte Relações.

Somente string, url, number, integer, boolean, datetime, select, reference e slug podem definir indexed: true. Em um campo reference, a flag só se aplica enquanto o campo não tiver relação, pois um campo vinculado não tem coluna para indexar.

Validação do campo

O schema de collection gerado reconhece estas regras onde o tipo de campo as suporta:

RegraUsada por
min, maxCampos numéricos
minLength, maxLength, patternCampos em forma de string
optionsselect e multiSelect
subFields, minItems, maxItemsrepeater
allowedTypes, minItems, maxItemsblocks
allowedMimeTypesCampos de mídia

retiredTypes em um campo blocks é gerenciado pelo servidor. Remover um slug de allowedTypes o aposenta: os blocos armazenados existentes continuam válidos, mas os novos blocos não podem usá-lo.

validateSeed() não verifica em profundidade o tipo de cada regra em validation ou options. Uma regra inválida pode, portanto, passar na validação do seed e falhar mais tarde, quando o schema da collection é construído ou o conteúdo é gravado.

Relações

Uma relação une duas collections e é dona dos links entre as suas entradas. Um campo reference se vincula a uma delas e vê os seus links a partir de uma extremidade. O seed a seguir declara uma relação entre posts e authors que permite um autor por post:

{
	"relations": [
		{
			"slug": "post_authors",
			"parentCollection": "posts",
			"childCollection": "authors",
			"parentLabel": "Posts",
			"parentLabelSingular": "Post",
			"childLabel": "Authors",
			"childLabelSingular": "Author",
			"maxChildrenPerParent": 1
		}
	]
}
PropriedadeTipoObrigatóriaDescrição
slugstringSimNome único pelo qual um campo reference a endereça
parentCollectionstringSimCollection na extremidade pai
childCollectionstringSimCollection na extremidade filha
parentLabelstringSimNomeia o papel do pai, visto a partir do filho
parentLabelSingularstringNãoForma singular de parentLabel
childLabelstringSimNomeia o papel do filho, visto a partir do pai
childLabelSingularstringNãoForma singular de childLabel
maxChildrenPerParentnumber | nullNãoQuantos filhos um pai pode vincular (null: sem limite)
maxParentsPerChildnumber | nullNãoQuantos pais um filho pode vincular (null: sem limite)

Um campo reference em collections nomeia a relação à qual se vincula:

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

Um campo pode, em vez disso, nomear uma targetCollection e fazer com que uma relação seja criada para ele, que é o caminho mais curto para um link que apenas uma collection vê. Declare a relação em relations quando ambas as collections devem vê-la, ou para definir seus rótulos e limites. reference documenta ambas as formas e as chaves de validação que cada uma aceita.

As duas collections de uma relação ficam fixas depois que ela existe: um seed que nomeia outras falha, em vez de deixar os links que ela guarda apontarem para uma collection que não é mais uma extremidade dela. Os rótulos e os limites são atualizados quando o seed é aplicado com onConflict: "update".

Taxonomias

As definições de taxonomia identificam suas collections de destino. Os termos são dados de exemplo e só são aplicados quando 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" }
      ]
    }
  ]
}

Uma taxonomia pode ter um id local do seed, locale e translationOf. Os termos também podem ter essas propriedades. translationOf se refere a outro ID local do seed. Um termo deve ser ordenado depois do termo que ele traduz. As entradas de taxonomia com o mesmo name podem aparecer em qualquer ordem, porque a entrada que declara a estrutura da taxonomia é aplicada antes das suas traduções.

hierarchical e collections são compartilhados por todos os locales de uma taxonomia, portanto uma entrada de taxonomia cujo translationOf aponta para uma entrada com o mesmo name pode omiti-los. O mecanismo de aplicação segue translationOf através das entradas com o mesmo name e os toma da última. A validação avisa quando uma tradução declara valores diferentes dos que ela toma, ou quando duas entradas que os declaram para uma mesma taxonomia discordam. Uma taxonomia existente mantém seus valores, a menos que uma entrada sem translationOf os substitua. Isso acontece com onConflict: "update", e em todos os modos quando o locale da entrada tem a definição integrada category ou tag sem modificações descrita em Comportamento de conflito, ou quando essa definição integrada é a única da taxonomia. A exportação os grava apenas na entrada para a qual as traduções apontam.

O parent de um termo é o slug do termo pai no mesmo locale. Um pai em uma taxonomia não hierárquica produz um aviso e é ignorado. Um termo com translationOf e sem parent toma o pai do termo que ele traduz.

Bylines

Os bylines raiz definem créditos de apresentação. São dados de exemplo e exigem includeContent: true.

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

O id é local do seed e é usado pelos créditos do conteúdo. As propriedades opcionais são bio, websiteUrl, isGuest e avatar.

O avatar de um byline aponta para um arquivo que já existe no armazenamento configurado:

{
  "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
  }
}

A semeadura do avatar de um byline cria ou reutiliza uma linha de mídia para a chave de armazenamento. Ela não envia nem baixa o arquivo.

Conteúdo

content agrupa as entradas por slug da collection. Cada entrada exige um id local do seed e um objeto data. As collections routable também exigem um slug não vazio.

{
  "version": "1",
  "content": {
    "posts": [
      {
        "id": "post-welcome",
        "slug": "welcome",
        "status": "published",
        "data": {
          "title": "Welcome",
          "content": []
        },
        "taxonomies": {
          "category": ["engineering"]
        },
        "bylines": [
          { "byline": "byline-editor", "roleLabel": "Editor" }
        ]
      }
    ]
  }
}
PropriedadeObrigatóriaComportamento
idSimID de referência local do seed
slugPara collections routableSlug público e chave de conflito
statusNãopublished ou draft; o padrão é published
dataSimValores indexados pelo slug de campo da collection
taxonomiesNãoNome da taxonomia para array de slugs de termos
bylinesNãoCréditos ordenados que referenciam IDs de byline raiz
localeNãoLocale BCP 47; o padrão vem de defaultLocale
translationOfNãoID de conteúdo local do seed na mesma collection

Para uma entrada routable, o id local do seed não é a sua identidade no banco de dados. O EmDash cria um ID de banco de dados e registra o mapeamento para referências posteriores. Para uma entrada sem slug em uma collection com routable: false, o EmDash usa o id do seed como ID armazenado, de modo que reaplicar continue idempotente.

Nas leituras, entry.id é o identificador de rota do Astro e normalmente é o slug. O ID armazenado no banco de dados é entry.data.id.

Referências de conteúdo

Use uma string $ref: dentro de data para substituir um ID de conteúdo local do seed pelo ID de banco de dados criado:

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

Os destinos de referência devem aparecer cedo o bastante para estarem presentes no mapa de IDs do mecanismo de aplicação. Um valor $ref: não resolvido permanece como a string literal original; validateSeed() não o rejeita.

Para um campo reference, declare os links a partir da extremidade pai da sua relação. As duas extremidades veem um mesmo conjunto de links, então um campo na collection filha repetiria links que o pai já carrega.

Referências de mídia

Use $media nos dados de conteúdo para baixar uma URL, enviá-la com o adaptador de armazenamento fornecido, criar uma linha de mídia e substituir o objeto por um valor de campo de mídia:

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

Em um bloco image de Portable Text ou em uma imagem de gallery, $media em asset se torna uma referência de mídia (_type: "reference", _ref, url, provider), e o texto alternativo e as dimensões da mídia preenchem o alt, o width e o height da própria imagem quando estão ausentes.

Dentro de uma mesma chamada de aplicação, referências repetidas à mesma URL reutilizam o valor de mídia já resolvido. As referências de mídia do seed não aceitam uma propriedade local file. mediaBasePath permanece no tipo público SeedApplyOptions, mas o mecanismo de aplicação atual não o lê.

Quando nenhum adaptador de armazenamento é fornecido, as referências $media são ignoradas e resolvem para null. Com skipMediaDownload: true, elas se tornam valores de mídia externos e nenhum adaptador de armazenamento é necessário.

Os menus são dados estruturais e são aplicados mesmo quando 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"
        }
      ]
    }
  ]
}

Os tipos de item permitidos são custom, page, post, taxonomy e collection. custom exige url; page e post exigem ref. Os itens podem incluir id, translationOf, label, collection, titleAttr, cssClasses, locale, target e children aninhados.

Para page e post, ref nomeia um ID de conteúdo do seed. Um destino ausente produz um aviso de validação e um item de menu sem referência de conteúdo resolvida. Os itens de menu existentes são excluídos e recriados sempre que esse menu é aplicado, independentemente de onConflict.

Redirecionamentos

Os redirecionamentos exigem caminhos de origem e de destino locais:

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

Ambos os caminhos devem começar com uma única /. URLs relativas ao protocolo, segmentos de path traversal e quebras de linha são rejeitados. Os códigos de status permitidos são 301, 302, 307 e 308.

Áreas de widget

Uma área de widgets contém widgets content, menu ou 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 }
        }
      ]
    }
  ]
}

Um widget content armazena Portable Text em content. Um widget menu exige menuName. Um widget component exige componentId e pode passar props. SeedWidget não tem a propriedade settings.

Os widgets existentes em uma área são excluídos e recriados sempre que a área é aplicada, independentemente de onConflict.

Sections

As sections contêm conteúdo reutilizável de Portable Text:

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

Os slugs de section contêm letras minúsculas, dígitos e hifens. source é theme, user ou import; um seed o define como theme por padrão. As sections de tema não podem ser excluídas na administração. As sections são estruturais e são aplicadas mesmo quando includeContent é false.

Localização

defaultLocale preenche os locales ausentes em taxonomias, termos, menus, itens de menu e conteúdo. A configuração i18n ativa em runtime tem precedência quando presente.

As taxonomias, os termos, os menus, os itens de menu e o conteúdo localizados usam os campos id e translationOf locais do seed. Coloque o item de origem antes de uma tradução para que o mecanismo de aplicação possa resolver o seu grupo de tradução. Uma entrada de conteúdo traduzida deve definir locale, e o seu translationOf deve nomear outra entrada da mesma collection.

Aplicar um seed programaticamente

applySeed() e validateSeed() são exportados de emdash/seed. O helper a seguir valida antes de aplicar:

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

OpçãoPadrãoComportamento atual
includeContentfalseInclui entradas de conteúdo, bylines e termos de taxonomia
onConflict"skip""skip", "update" ou "error" para os conflitos de entidades suportadas
storagenenhumAdaptador de armazenamento necessário para baixar URLs $media
skipMediaDownloadfalseMantém as URLs $media como valores de mídia externos
mediaBasePathnenhumPresente no tipo público, mas não usado pelo mecanismo de aplicação atual

A aplicação programática define includeContent como false por padrão. O assistente de configuração repassa a escolha do administrador sobre o conteúdo de exemplo. A CLI emdash seed inclui o conteúdo por padrão, a menos que --no-content seja definido.

Comportamento de conflito

onConflict não é uma política de transação para todo o seed:

  • Collections, campos, bylines, conteúdo, redirecionamentos e sections suportam os comportamentos skip, update e error.
  • As definições de taxonomia e os termos respeitam o modo de conflito aplicável. A exceção são as definições integradas category e tag com as quais cada novo banco de dados começa: até que um site as edite, um seed que as declare as substitui em todos os modos.
  • As configurações usam tratamento de conflito por chave. skip cria as configurações ausentes e preserva os valores existentes. update sobrescreve cada configuração fornecida; para seo e social, apenas os campos fornecidos são sobrescritos. error para na primeira configuração existente; as configurações criadas antes na ordem do seed permanecem aplicadas.
  • Os menus existentes mantêm a sua linha de menu, mas substituem todos os itens.
  • As áreas de widgets existentes mantêm a sua linha de área, mas substituem todos os widgets.
  • Um conflito de conteúdo é correspondido por collection, slug e locale. Uma entrada sem slug em uma collection não routable é correspondida pelo seu ID do seed.

Com onConflict: "update", os dados de conteúdo são substituídos e as suas atribuições de byline e taxonomia são reconciliadas com o seed. Teste o modo update em uma cópia antes de usá-lo em um site existente.

applySeed() retorna contadores para collections, campos, taxonomias, bylines, menus, redirecionamentos, áreas de widgets, sections, configurações, conteúdo e mídia.

Comportamento de validação

validateSeed() retorna { valid, errors, warnings }. applySeed() o chama e lança Invalid seed file quando há erros.

O validador verifica as regras estruturais exigidas pelo mecanismo de aplicação, incluindo:

  • Versão e defaultLocale não vazio.
  • Formas dos contêineres de collection, campo, taxonomia, termo, menu, área de widgets, section, byline e conteúdo.
  • Nomes, rótulos, IDs, slugs obrigatórios e tipos de campo ou widget suportados.
  • Identificadores duplicados no escopo relevante.
  • Tipos de campo indexáveis e referências de admin.listColumns.
  • Pais de taxonomia, traduções de conteúdo, referências de byline no conteúdo e requisitos dos itens de menu.
  • Caminhos de redirecionamento locais seguros e códigos de status.

Algumas condições são avisos, e não erros. Exemplos: uma taxonomia sem collections, um pai em uma taxonomia plana ou uma referência de conteúdo de menu ausente do seed.

O validador não prova que todos os valores data estão em conformidade com os campos da sua collection. Ele também não valida em profundidade as configurações do site, a validation do campo, as options do campo, blocos Portable Text arbitrários, as props dos widgets component, os destinos $ref: nos dados de conteúdo nem a disponibilidade remota de $media. Um seed válido ainda pode falhar durante a criação do schema, a validação do conteúdo, o download pela rede ou o upload para o armazenamento.

Use a URL $schema para auxílio do editor e execute o validador executável antes de aplicar:

npx emdash seed seed/seed.json --validate

Comandos da CLI

Aplique um seed a um banco de dados SQLite local com um comportamento de conflito explícito:

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

Exporte o modelo local atual e todo o conteúdo de volta para o caminho do template:

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

export-seed funciona diretamente em um arquivo SQLite local. Para um banco de dados D1 implantado, exporte-o primeiro para um arquivo local. Revise as configurações, o conteúdo e as referências de mídia exportados antes de fazer o commit do resultado. Para tornar a mídia exportada importável em outro site, passe --media-base-url; consulte URLs de mídia.

Próximos passos