Archivos seed

En esta página

Un archivo seed describe el modelo inicial y los datos de ejemplo opcionales de un sitio EmDash. Las plantillas actuales lo almacenan en seed/seed.json y apuntan a él con package.json#emdash.seed.

EmDash incrusta el seed en tiempo de compilación. Está pensado para la primera configuración y comandos seed explícitos, no como una migración que se ejecuta en cada despliegue.

Descubrimiento del archivo

La integración de Astro busca un seed en este orden:

  1. .emdash/seed.json.
  2. La ruta en package.json#emdash.seed.
  3. seed/seed.json.
  4. El seed predeterminado integrado cuando no existe un seed de usuario.

El siguiente campo del paquete selecciona la ruta convencional de la plantilla:

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

Forma raíz

El siguiente ejemplo contiene todas las propiedades raíz:

{
  "$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": []
}
PropiedadObligatoriaPropósito
$schemaNoURL del esquema para el editor
versionSíFormato del seed; el único valor aceptado es "1"
defaultLocaleNoLocale para las filas con locale que omiten locale; por defecto la configuración en tiempo de ejecución y después en
metaNoNombre descriptivo, descripción y autor que se muestran durante la configuración
settingsNoAjustes parciales del sitio
blockTypesNoDefiniciones versionadas usadas por los campos blocks
collectionsNoDefiniciones de collections y campos
taxonomiesNoDefiniciones de taxonomías y términos opcionales
bylinesNoPerfiles opcionales de créditos de presentación
contentNoEntradas de ejemplo agrupadas por slug de collection
menusNoMenús y elementos anidados
redirectsNoReglas de redirección locales
widgetAreasNoÁreas de widgets y widgets
sectionsNoSections reutilizables de Portable Text

defaultLocale debe ser una cadena no vacía, sin espacios al principio ni al final.

Ajustes

settings es un objeto parcial de ajustes del sitio. Las propiedades habituales son title, tagline, logo, favicon, url, postsPerPage, dateFormat, timezone, social y seo.

El asistente de configuración permite al administrador reemplazar el título y el eslogan sembrados. El valor predeterminado onConflict: "skip" conserva esos valores cuando el seed se aplica de nuevo y completa cualquier ajuste suministrado que todavía falte.

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

Tipos de bloque

blockTypes define las formas versionadas que usan los campos de collection blocks. EmDash aplica estas definiciones antes que las collections, de modo que un campo puede nombrarlas en validation.allowedTypes.

El siguiente seed mantiene la versión 1 para el contenido y las revisiones almacenados, y hace activa la versión 2 para los bloques nuevos:

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

Los números de versión son enteros positivos contiguos que empiezan en 1. currentVersion debe nombrar una versión declarada. Exportar y volver a aplicar un seed conserva los números de versión exactos y el puntero a la versión activa; EmDash no los renumera.

Con onConflict: "update", un seed puede modificar una versión almacenada solo cuando la nueva definición es compatible. Reutilizar un número existente para una definición incompatible falla con BLOCK_TYPE_VERSION_CONFLICT. Añada un número de versión nuevo para una definición que rompa la compatibilidad.

Los valores de bloque almacenados incluyen _type, _version y _key. Proporcione esas propiedades cuando el contenido del seed apunte a una versión conservada. El tiempo de ejecución asigna la versión activa y una clave cuando un bloque recién escrito las omite.

Collections

Una collection requiere slug, label y 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" }
      ]
    }
  ]
}

Propiedades de collection

PropiedadTipoComportamiento
slugstringNombre obligatorio de base de datos y API; empieza con una letra minúscula y contiene letras minúsculas, dígitos y guiones bajos
labelstringEtiqueta de IU obligatoria en plural
labelSingularstringEtiqueta de IU opcional en singular
descriptionstringDescripción opcional en la administración
iconstringNombre del icono de Phosphor para la entrada de la barra lateral, como calendar-blank
admin.listColumnsstring[]Hasta cuatro slugs de campos declarados que se muestran en la lista de contenido
admin.quickCreatebooleanSi el panel muestra una acción rápida «Nueva entrada» para esta collection; por defecto true
supportsstring[]Cualquiera de drafts, revisions, preview, scheduling, search y seo
urlPatternstringPatrón público como /posts/{slug}, con como máximo un marcador de posición por segmento de ruta
routablebooleanSi las entradas publicadas requieren un slug; por defecto true
hiddenbooleanOculta el enlace generado de la barra lateral, el enlace de la paleta de comandos y la acción rápida del panel; la collection sigue accesible por URL y API
sortOrdernumberPosición explícita en la barra lateral de la administración; las collections ordenadas van primero, en orden ascendente
groupstringCarpeta de la barra lateral de la administración; las collections con el mismo grupo comparten una entrada plegable
commentsEnabledbooleanActiva los comentarios para la collection
editLockingbooleanActiva los bloqueos de edición; por defecto true
titleFieldstringCampo usado para el título en la lista de contenido
dateFieldstringCampo datetime usado para la fecha en la lista de contenido
fieldsSeedField[]Definiciones de campo obligatorias

sortOrder pertenece a la collection y controla el orden de la barra lateral. SeedField no tiene la propiedad sortOrder. Los campos se crean en el orden de su array.

Propiedades de campo

PropiedadTipoPropósito
slugstringNombre de campo obligatorio con el patrón del slug de collection
labelstringEtiqueta de IU obligatoria
typeFieldTypeTipo de campo almacenado obligatorio
requiredbooleanRechaza un valor obligatorio vacío
uniquebooleanAñade una restricción de unicidad
searchablebooleanIncluye el campo en la búsqueda de la collection
indexedbooleanAñade un índice de consulta para los tipos escalares admitidos
translatablebooleanAlmacena un valor por locale; por defecto true. false comparte un único valor entre las traducciones
defaultValuecualquieraValor inicial cuando se omite el campo
validationobjetoReglas de validación usadas por los esquemas de contenido generados
widgetstringSustitución del widget del campo en la administración
optionsobjetoOpciones específicas del widget

Los tipos de campo admitidos son:

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

Un campo reference no almacena nada en la tabla de la collection. Sus enlaces viven en la relación a la que está vinculado; consulte Relaciones.

Solo string, url, number, integer, boolean, datetime, select, reference y slug pueden establecer indexed: true. En un campo reference, la marca solo se aplica mientras el campo no tenga relación, ya que un campo vinculado no tiene columna que indexar.

Validación de campo

El esquema de collection generado reconoce estas reglas donde el tipo de campo las admite:

ReglaUsada por
min, maxCampos numéricos
minLength, maxLength, patternCampos con forma de cadena
optionsselect y multiSelect
subFields, minItems, maxItemsrepeater
allowedTypes, minItems, maxItemsblocks
allowedMimeTypesCampos de medios

retiredTypes en un campo blocks lo gestiona el servidor. Quitar un slug de allowedTypes lo retira: los bloques almacenados existentes siguen siendo válidos, pero los bloques nuevos no pueden usarlo.

validateSeed() no comprueba en profundidad el tipo de cada regla en validation u options. Por tanto, una regla no válida puede pasar la validación del seed y fallar más tarde, cuando se construye el esquema de la collection o se escribe contenido.

Relaciones

Una relación une dos collections y es propietaria de los enlaces entre sus entradas. Un campo reference se vincula a una de ellas y ve sus enlaces desde un extremo. El siguiente seed declara una relación entre posts y authors que permite un autor por publicación:

{
	"relations": [
		{
			"slug": "post_authors",
			"parentCollection": "posts",
			"childCollection": "authors",
			"parentLabel": "Posts",
			"parentLabelSingular": "Post",
			"childLabel": "Authors",
			"childLabelSingular": "Author",
			"maxChildrenPerParent": 1
		}
	]
}
PropiedadTipoObligatoriaDescripción
slugstringSíNombre único con el que un campo reference la direcciona
parentCollectionstringSíCollection en el extremo padre
childCollectionstringSíCollection en el extremo hijo
parentLabelstringSíNombra el papel del padre, visto desde el hijo
parentLabelSingularstringNoForma singular de parentLabel
childLabelstringSíNombra el papel del hijo, visto desde el padre
childLabelSingularstringNoForma singular de childLabel
maxChildrenPerParentnumber | nullNoCuántos hijos puede vincular un padre (null: sin límite)
maxParentsPerChildnumber | nullNoCuántos padres puede vincular un hijo (null: sin límite)

Un campo reference en collections nombra la relación a la que se vincula:

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

Un campo puede nombrar en su lugar una targetCollection y hacer que se cree una relación para él, que es el camino más corto para un enlace que solo ve una collection. Declare la relación en relations cuando ambas collections deban verla, o para establecer sus etiquetas y límites. reference documenta ambas formas y las claves de validación que acepta cada una.

Las dos collections de una relación quedan fijas una vez que existe: un seed que nombre otras falla, en lugar de dejar que los enlaces que contiene apunten a una collection que ya no es un extremo de ella. Las etiquetas y los límites se actualizan cuando el seed se aplica con onConflict: "update".

Taxonomías

Las definiciones de taxonomía identifican sus collections de destino. Los términos son datos de ejemplo y solo se aplican cuando includeContent es 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" }
      ]
    }
  ]
}

Una taxonomía puede llevar un id local del seed, locale y translationOf. Los términos también pueden llevar esas propiedades. translationOf se refiere a otro ID local del seed. Un término debe ordenarse después del término que traduce. Las entradas de taxonomía con el mismo name pueden aparecer en cualquier orden, porque la entrada que declara la estructura de la taxonomía se aplica antes que sus traducciones.

hierarchical y collections son compartidos por todos los locales de una taxonomía, por lo que una entrada de taxonomía cuyo translationOf apunta a una entrada con el mismo name puede omitirlos. El motor de aplicación sigue translationOf a través de las entradas con el mismo name y los toma de la última. La validación advierte cuando una traducción declara valores distintos de los que toma, o cuando dos entradas que los declaran para una misma taxonomía no coinciden. Una taxonomía existente conserva sus valores, a menos que una entrada sin translationOf los reemplace. Eso ocurre con onConflict: "update", y en todos los modos cuando el locale de la entrada tiene la definición integrada category o tag sin modificar descrita en Comportamiento de conflictos, o cuando esa definición integrada es la única de la taxonomía. La exportación los escribe solo en la entrada a la que apuntan las traducciones.

El parent del término es el slug del término padre en el mismo locale. Un parent en una taxonomía no jerárquica produce una advertencia y se ignora. Un término con translationOf y sin parent toma el parent del término que traduce.

Bylines

Los bylines raíz definen créditos de presentación. Son datos de ejemplo y requieren includeContent: true.

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

El id es local del seed y lo usan los créditos del contenido. Las propiedades opcionales son bio, websiteUrl, isGuest y avatar.

El avatar de un byline apunta a un archivo que ya existe en el almacenamiento 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
  }
}

La siembra del avatar de un byline crea o reutiliza una fila de medios para la clave de almacenamiento. No sube ni descarga el archivo.

Contenido

content agrupa las entradas por slug de collection. Cada entrada requiere un id local del seed y un objeto data. Las collections routables también requieren un slug no vacío.

{
  "version": "1",
  "content": {
    "posts": [
      {
        "id": "post-welcome",
        "slug": "welcome",
        "status": "published",
        "data": {
          "title": "Welcome",
          "content": []
        },
        "taxonomies": {
          "category": ["engineering"]
        },
        "bylines": [
          { "byline": "byline-editor", "roleLabel": "Editor" }
        ]
      }
    ]
  }
}
PropiedadObligatoriaComportamiento
idSíID de referencia local del seed
slugEn collections routablesSlug público y clave de conflicto
statusNopublished o draft; por defecto published
dataSíValores indexados por el slug de campo de la collection
taxonomiesNoNombre de taxonomía a array de slugs de términos
bylinesNoCréditos ordenados que hacen referencia a IDs de byline raíz
localeNoLocale BCP 47; por defecto mediante defaultLocale
translationOfNoID de contenido local del seed en la misma collection

Para una entrada routable, el id local del seed no es su identidad en la base de datos. EmDash crea un ID de base de datos y registra la correspondencia para referencias posteriores. Para una entrada sin slug en una collection con routable: false, EmDash usa el id del seed como ID almacenado, de modo que volver a aplicarlo siga siendo idempotente.

En las lecturas, entry.id es el identificador de ruta de Astro y normalmente es el slug. El ID almacenado en la base de datos es entry.data.id.

Referencias de contenido

Use una cadena $ref: dentro de data para reemplazar un ID de contenido local del seed por el ID de base de datos creado:

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

Los destinos de referencia deben aparecer con suficiente antelación para estar presentes en el mapa de IDs del motor de aplicación. Un valor $ref: sin resolver permanece como la cadena literal original; validateSeed() no lo rechaza.

Para un campo reference, declare los enlaces desde el extremo padre de su relación. Ambos extremos ven un mismo conjunto de enlaces, así que un campo en la collection hija repetiría enlaces que el padre ya lleva.

Referencias de medios

Use $media en los datos de contenido para descargar una URL, subirla con el adaptador de almacenamiento suministrado, crear una fila de medios y reemplazar el objeto por un valor de campo de medios:

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

En un bloque image de Portable Text o en una imagen de gallery, $media en asset se convierte en una referencia de medios (_type: "reference", _ref, url, provider), y el texto alternativo y las dimensiones del medio rellenan el alt, el width y el height propios de la imagen cuando faltan.

Dentro de una llamada de aplicación, las referencias repetidas a la misma URL reutilizan el valor de medios ya resuelto. Las referencias de medios del seed no aceptan una propiedad local file. mediaBasePath sigue en el tipo público SeedApplyOptions, pero el motor de aplicación actual no la lee.

Cuando no se suministra un adaptador de almacenamiento, las referencias $media se omiten y se resuelven como null. Con skipMediaDownload: true, se convierten en valores de medios externos y no se requiere adaptador de almacenamiento.

Menús

Los menús son datos estructurales y se aplican incluso cuando includeContent es 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"
        }
      ]
    }
  ]
}

Los tipos de elemento permitidos son custom, page, post, taxonomy y collection. custom requiere url; page y post requieren ref. Los elementos pueden incluir id, translationOf, label, collection, titleAttr, cssClasses, locale, target y children anidados.

Para page y post, ref nombra un ID de contenido del seed. Un destino ausente produce una advertencia de validación y un elemento de menú sin referencia de contenido resuelta. Los elementos de menú existentes se eliminan y se vuelven a crear cada vez que se aplica ese menú, independientemente de onConflict.

Redirecciones

Las redirecciones requieren rutas de origen y de destino locales:

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

Ambas rutas deben empezar con una sola /. Se rechazan las URL relativas al protocolo, los segmentos de recorrido de ruta y los saltos de línea. Los códigos de estado permitidos son 301, 302, 307 y 308.

Áreas de widgets

Un área de widgets contiene widgets content, menu o 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 }
        }
      ]
    }
  ]
}

Un widget content almacena Portable Text en content. Un widget menu requiere menuName. Un widget component requiere componentId y puede pasar props. SeedWidget no tiene la propiedad settings.

Los widgets existentes en un área se eliminan y se vuelven a crear cada vez que se aplica el área, independientemente de onConflict.

Sections

Las sections contienen contenido reutilizable de Portable Text:

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

Los slugs de section contienen letras minúsculas, dígitos y guiones. source es theme, user o import; un seed lo establece por defecto en theme. Las sections de tema no se pueden eliminar en la administración. Las sections son estructurales y se aplican incluso cuando includeContent es false.

Localización

defaultLocale rellena los locales que faltan en taxonomías, términos, menús, elementos de menú y contenido. La configuración i18n activa en tiempo de ejecución tiene prioridad cuando existe.

Las taxonomías, los términos, los menús, los elementos de menú y el contenido localizados usan los campos id y translationOf locales del seed. Coloque el elemento de origen antes de una traducción para que el motor de aplicación pueda resolver su grupo de traducción. Una entrada de contenido traducida debe establecer locale, y su translationOf debe nombrar otra entrada de la misma collection.

Aplicar un seed de forma programática

applySeed() y validateSeed() se exportan desde emdash/seed. El siguiente helper 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

OpciónValor por defectoComportamiento actual
includeContentfalseIncluye entradas de contenido, bylines y términos de taxonomía
onConflict"skip""skip", "update" o "error" para los conflictos de entidades admitidas
storageningunoAdaptador de almacenamiento necesario para descargar URL $media
skipMediaDownloadfalseMantiene las URL $media como valores de medios externos
mediaBasePathningunoPresente en el tipo público, pero no lo usa el motor de aplicación actual

La aplicación programática establece includeContent en false por defecto. El asistente de configuración pasa la elección del administrador sobre el contenido de ejemplo. La CLI emdash seed incluye contenido por defecto, salvo que se establezca --no-content.

Comportamiento de conflictos

onConflict no es una política de transacción para todo el seed:

  • Collections, campos, bylines, contenido, redirecciones y sections admiten comportamiento de omitir, actualizar y error.
  • Las definiciones y términos de taxonomía respetan el modo de conflicto aplicable. La excepción son las definiciones integradas category y tag con las que empieza cada base de datos nueva: hasta que un sitio las edite, un seed que las declare las reemplaza en cada modo.
  • Los ajustes usan manejo de conflictos por clave. skip crea los ajustes que faltan y conserva los valores existentes. update sobrescribe cada ajuste suministrado; para seo y social, solo se sobrescriben los campos suministrados. error se detiene en el primer ajuste existente; los ajustes creados antes en el orden del seed permanecen aplicados.
  • Los menús existentes conservan su fila de menú pero reemplazan todos los elementos.
  • Las áreas de widgets existentes conservan su fila de área pero reemplazan todos los widgets.
  • Un conflicto de contenido se empareja por collection, slug y locale. Una entrada sin slug en una collection no routable se empareja por su ID de seed.

Con onConflict: "update", los datos de contenido se reemplazan y sus asignaciones de byline y taxonomía se concilian con el seed. Pruebe el modo de actualización en una copia antes de usarlo contra un sitio existente.

applySeed() devuelve contadores para collections, campos, taxonomías, bylines, menús, redirecciones, áreas de widgets, sections, ajustes, contenido y medios.

Comportamiento de validación

validateSeed() devuelve { valid, errors, warnings }. applySeed() lo llama y lanza Invalid seed file cuando hay errores.

El validador comprueba las reglas estructurales que requiere el motor de aplicación, incluyendo:

  • Versión y defaultLocale no vacío.
  • Formas de los contenedores de collection, campo, taxonomía, término, menú, área de widgets, section, byline y contenido.
  • Nombres, etiquetas, IDs, slugs requeridos y tipos de campo o widget admitidos.
  • Identificadores duplicados en su ámbito relevante.
  • Tipos de campo indexables y referencias de admin.listColumns.
  • Padres de taxonomía, traducciones de contenido, referencias de byline en el contenido y requisitos de los elementos de menú.
  • Rutas de redirección locales seguras y códigos de estado.

Algunas condiciones son advertencias en lugar de errores. Ejemplos: una taxonomía sin collections, un padre en una taxonomía plana o una referencia de contenido de menú ausente del seed.

El validador no demuestra que todos los valores data se ajusten a sus campos de collection. Tampoco valida en profundidad los ajustes del sitio, la validation del campo, las options del campo, bloques Portable Text arbitrarios, props de widgets component, destinos $ref: en datos de contenido ni la disponibilidad remota de $media. Un seed válido aún puede fallar durante la creación del esquema, la validación de contenido, la descarga de red o la subida al almacenamiento.

Use la URL $schema para ayuda del editor y ejecute el validador ejecutable antes de aplicar:

npx emdash seed seed/seed.json --validate

Comandos CLI

Aplique un seed a una base de datos SQLite local con un comportamiento de conflicto explícito:

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

Exporte el modelo local actual y todo el contenido de vuelta a la ruta de la plantilla:

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

export-seed funciona directamente sobre un archivo SQLite local. Para una base de datos D1 desplegada, expórtela primero a un archivo local. Revise los ajustes, el contenido y las referencias de medios exportados antes de confirmar el resultado. Para que los medios exportados se puedan importar en otro sitio, pase --media-base-url; consulte URL de medios.

Siguientes pasos