Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
01ddefc
bulk import and export
marcelofinamorvieira Aug 14, 2025
02612fa
removed temp files
marcelofinamorvieira Aug 14, 2025
df2205a
removed overviews, better global substitution rules
marcelofinamorvieira Sep 15, 2025
2b6078c
better conflict manager
marcelofinamorvieira Sep 15, 2025
ba6da8f
simplify
marcelofinamorvieira Sep 17, 2025
db508ba
refactor
marcelofinamorvieira Sep 17, 2025
f18ca1d
fix dependencies
marcelofinamorvieira Sep 18, 2025
5385ecb
fix
marcelofinamorvieira Sep 18, 2025
6697e8e
refactor 2 - eletric boogaloo
marcelofinamorvieira Sep 18, 2025
738327a
better export screen
marcelofinamorvieira Sep 18, 2025
12f7318
better conflict manager
marcelofinamorvieira Sep 19, 2025
07dcaa1
better export overview
marcelofinamorvieira Sep 19, 2025
13d847d
export finished
marcelofinamorvieira Sep 19, 2025
def457f
change
marcelofinamorvieira Sep 19, 2025
f2fc517
refactor
marcelofinamorvieira Sep 19, 2025
e9e3a80
removed header
marcelofinamorvieira Sep 22, 2025
29da848
removed unused code
marcelofinamorvieira Sep 22, 2025
f3ba36b
refactor
marcelofinamorvieira Sep 22, 2025
a0ea958
better close
marcelofinamorvieira Sep 22, 2025
cdae91d
sidebar
marcelofinamorvieira Sep 22, 2025
e028407
final design
marcelofinamorvieira Sep 22, 2025
8d083ec
refactor
marcelofinamorvieira Sep 22, 2025
674ecfe
new large view
marcelofinamorvieira Sep 23, 2025
ef48345
refactor
marcelofinamorvieira Sep 23, 2025
964dcaa
refactor
marcelofinamorvieira Sep 23, 2025
c9c137b
roolback
marcelofinamorvieira Sep 23, 2025
ee7eda2
remove
marcelofinamorvieira Sep 23, 2025
2ea5e40
types
marcelofinamorvieira Sep 23, 2025
2bc20a9
rollbackfix
marcelofinamorvieira Sep 23, 2025
e6764d7
fix appearences
marcelofinamorvieira Oct 13, 2025
99bc3dd
fix
marcelofinamorvieira Oct 13, 2025
85eda6e
version bump
marcelofinamorvieira Oct 13, 2025
63cb9f7
plugin conflict bug fix
marcelofinamorvieira Oct 22, 2025
510e692
Update version to 0.1.19, enhance root item type coverage logic, and …
marcelofinamorvieira Nov 10, 2025
4d8d836
Add d3-timer dependency and update TypeScript build info versions
marcelofinamorvieira Nov 10, 2025
3c84f36
Update version to 0.1.20 and improve validation logic in ResolutionsF…
marcelofinamorvieira Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions import-export-schema/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ node_modules
dist
dist-ssr
*.local
*.tsbuildinfo

# Editor directories and files
.vscode/*
Expand All @@ -24,3 +25,5 @@ dist-ssr
*.sw?

.tmplr-preview

AGENTS.md
148 changes: 101 additions & 47 deletions import-export-schema/README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,110 @@
# DatoCMS Schema Import/Export Plugin

A powerful plugin for DatoCMS that enables seamless schema migration between projects through JSON import/export functionality.
Powerful, safe schema migration for DatoCMS. Export models/blocks and plugins as JSON, then import them into another project with guided conflict resolution.

## Features
## What it does

- Export single or multiple models/block models as JSON files
- Import models into different DatoCMS projects
- Smart conflict resolution with guided instructions
- Automatic plugin dependency detection and inclusion
- Safe import operations that preserve existing schema
- Builds dependency-aware exports: collects selected models, blocks, fieldsets, fields, and any referenced plugins while trimming validators that point to out-of-scope item types.
- Keeps exports portable: rewrites field appearances to rely only on bundled or built-in editors and downloads a prettified `export.json` when each task completes.
- Imports additively: compares the bundle against the target project, walks you through reuse/rename/skip decisions, and creates new entities without mutating existing ones unless you opt in.
- Restores editors safely: reinstalls plugin editors/addons when present, falling back to core editors so fields always remain valid in the destination project.
- Handles long tasks gracefully: surfaces cancellable overlays with stall notices, honors rate-limit throttling, and stops at the next safe checkpoint if you cancel mid-flight.
- Loads shared recipes: accepts `recipe_url` query parameters to pull an export from a URL so collaborators can hand off ready-to-import snapshots.

## Safety Features
## Where To Find It

As a security measure, this plugin is designed to never modify existing schema entities in the target project during JSON imports. It only adds new entities to the project, making the operation completely safe and non-destructive.
- Configuration > Export: start a new export, select multiple models/blocks, or export the entire current environment.
- Configuration > Import: upload an export file (or paste a recipe URL) and import safely into the current environment.
- From a model/block: in Schema, open a model/block, click the three dots beside the model/block name, and pick “Export as JSON…”—the plugin opens the Export page preloaded with that entity so you can jump straight to the graph.

## Installation

1. Navigate to your DatoCMS environment configuration
2. Go to the Plugins section
3. Search for "Schema Import/Export"
4. Click Install

## Usage

### Exporting Models

1. In the Schema section, navigate to one of your models/block models
2. Select the "Export as JSON..." option
3. If the model/block model references other models/block models, you can decide to export them as well
4. Save the generated JSON file

### Importing Models

1. Navigate to your DatoCMS environment configuration
2. Go to the Import/Export section
3. Drop your JSON file
4. Follow the conflict resolution prompts if any appear
5. Confirm the import

## Conflict Resolution

When importing models, the plugin will:

- Detect potential conflicts with existing schema
- Provide clear instructions for resolving each conflict
- Allow you to review changes before applying them

## Dependencies

The plugin automatically handles the following dependencies:

- Required field plugins
- Block model relationships
- Field validations
- Field appearance settings
- In DatoCMS, open your project, go to Plugins, search for “Schema Import/Export”, then install. The plugin only requests `currentUserAccessToken`.

## Export

- Start from a model/block
- Open Schema, select a model/block.
- Click the three dots beside the model/block name and choose “Export as JSON…”.
- The Export page opens with that entity locked in the selection; inspect the graph/list, run “Select all dependencies” to pull in linked models/blocks/plugins, and undo it with “Unselect dependencies” if you change your mind.
- Start the export when ready; the long-task overlay shows progress/cancel options, and the prettified `export.json` downloads automatically once the task completes.

- Start a new export (Schema > Export)
- The landing panel lets you either pick specific starting models/blocks or go straight to “Export entire schema”.
- Use the multi-select to seed the graph; the graph animates selections for small/medium schemas, while large schemas (>60 nodes) fall back to the list view with search, metrics (counts, components, cycles), and “Why included?” explanations.
- “Select all dependencies” adds related models/blocks/plugins in bulk and logs a notice showing how many were added; “Unselect dependencies” removes the auto-added ones.
- Plugin dependencies come from installed plugin lookups; if the CMA call fails you’ll see a warning so you know selections may be incomplete.

- Export the entire schema (one click)
- Confirm the dialog to queue up every model, block, and plugin in the current environment.
- The overlay reports progress, handles cancellable requests, and falls back gracefully if the CMA throttles; the final file downloads as `export.json`.

- After export
- You get a success notice (or cancellation/error messaging) plus the downloaded file; the selection stays in place so you can tweak it and run another export without leaving the page.

## Import

- Start an import (Schema > Import)
- Drag and drop an exported JSON file or use the “Select a JSON export file…” button; invalid JSON triggers an alert so you can retry.
- To hydrate directly from a shared recipe, append `?recipe_url=https://…` (optional `recipe_title=…`)—the plugin fetches it and switches to import mode automatically.

- Resolve conflicts safely
- The plugin builds a conflict summary in the background with progress feedback; you can refresh it if the schema changes while you wait.
- For models/blocks: choose “Reuse existing” or “Rename” with inline validation for name/API key (preset suggestions are provided for fast renames).
- For plugins: choose “Reuse existing” or “Skip”.
- Use “Show only unresolved conflicts” to focus the list; entities marked “reuse” drop out of the graph/list so you stay focused on what will be created.
- The import graph mirrors the export graph for smaller selections and switches to the list view with metrics/search once the node count crosses the same 60-node threshold.

- Run the import
- Imports are additive: new models/blocks/fields/fieldsets/plugins are created with fresh IDs, and existing assets are touched only when you explicitly reuse them.
- Field validators and appearances are remapped to the target project; missing plugin editors fall back to safe defaults and localized defaults expand to every locale in the target environment.
- The progress overlay includes a cancel affordance with the required warning dialog; if you cancel, the task stops at the next safe checkpoint.

- After import
- Successful runs raise a notice and clear the loaded export; cancellations leave the file in place so you can try again, and failures keep the conflict form available for fixes.

## Notes & Limits

- Plugin detection: editor/addon plugins used by fields are included when “Select all dependencies” is used. If the installed plugin list cannot be fetched you’ll see a one-time banner (per session) so you know detection may be incomplete.
- Graph threshold: when the graph would exceed ~60 nodes the UI switches to the large-selection layout with search, metrics (counts/components/cycles), and “Why included?” reasoning instead of rendering an unreadable canvas.
- Rate limiting & throttling: long operations show a stall notice if progress pauses, and `ProjectSchema` throttles CMA calls by default (override with something like `localStorage.setItem('schemaThrottleMax', '8')`; valid values are 1–15 for local debugging).
- Appearance portability: if an editor plugin is not selected, that field falls back to a valid built‑in editor; addons are included only if selected or already installed.
- Debug logging: run `localStorage.setItem('schemaDebug', '1')` in the iframe console to enable detailed `debugLog` output.

## Development Notes

- Entry points:
- `src/main.tsx` registers plugin pages, schema dropdown shortcuts, and preserves environment-prefixed routing when navigating between Import/Export.
- `src/entrypoints/Config` uses `ctx.navigateTo` so config links jump directly to Schema, Import, or Export without reloading the iframe.
- Shared hooks:
- `useProjectSchema` memoizes the CMA client, caches item types/plugins/fields, and honors the `schemaThrottleMax` localStorage override.
- `useLongTask` tracks cancellable progress state shared by exports, imports, and conflict analysis.
- `useExportSelection` hydrates item types once and keeps the selection stable when the import page toggles between modes.
- `useExportGraph` assembles the React Flow graph/list data and streams progress updates for the preparation overlay.
- `useExportAllHandler` and `useSchemaExportTask` wrap `buildExportDoc`, download handling, progress overlays, and cancellation.
- `useConflictsBuilder` drives conflict analysis with `useLongTask`; `useRecipeLoader` watches `recipe_url` query params for shared exports.
- Shared UI:
- `TaskOverlayStack` + `TaskProgressOverlay` render cancellable overlays with `ProgressOverlay` stall detection.
- `GraphCanvas` and the Schema Overview components keep the export/import visualizations consistent, with large graph warnings gating heavy renders.
- Schema utilities:
- `ProjectSchema` provides cached lookups plus concurrency-limited `getItemTypeFieldsAndFieldsets` calls.
- `buildExportDoc` trims validators/appearances so exports stay self-contained; `buildImportDoc` + `importSchema` orchestrate plugin installs, item type creation, field migrations, and reorder passes.
- Local development:
- `npm run dev` starts Vite, `npm run build` runs `tsc -b` followed by `vite build`, `npm run analyze` builds with bundle analysis, and `npm run format` runs Biome in `--write` mode.

## Export File Format

- Version 2 (current): `{ version: '2', rootItemTypeId, entities: […] }` — preserves the explicit root model/block used to seed the export, to re-generate the export graph deterministically.
- Version 1 (legacy): `{ version: '1', entities: […] }` — still supported for import; the root is inferred from references.
- Field validators referencing models outside the selection are trimmed, and appearances are rewritten to include only allowed plugin editors/addons so the export remains self-contained.

## Safety

- Imports are additive and non‑destructive. The plugin never overwrites existing models/blocks or plugins. When conflicts are detected, you explicitly pick “Reuse existing” or “Rename”.

## Troubleshooting

- “Why did the graph disappear?” Large selections now show a warning instead of auto-rendering; click “Render it anyway” to view the full graph.
- “Fields lost their editor?” If you don’t include a custom editor plugin in the export/import, the plugin selects a safe, built‑in editor so the field remains valid in the target project.
- “Plugin dependencies were skipped?” Check for the banner warning about incomplete plugin detection and rerun “Select all dependencies” after reopening the page once the CMA call succeeds.
- “Cancel didn’t stop immediately?” The import/export pipeline stops at the next safe checkpoint; keep the overlay open until it confirms cancellation.
Loading