Skip to content

feat(cli): add firecms migrate rowy to turn Rowy tables into collections - #1026

Merged
marianmoldovan merged 2 commits into
mainfrom
feat/cli-migrate-rowy
Nov 2, 2026
Merged

marianmoldovan merged 2 commits into
mainfrom
feat/cli-migrate-rowy

Conversation

@marianmoldovan

Copy link
Copy Markdown
Collaborator

What

A new CLI command, firecms migrate rowy, that turns Rowy tables into FireCMS collections.

Rowy keeps every table's settings in the project's own Firestore, under _rowy_ (_rowy_/settings, and the columns in _rowy_/settings/schema/{tableId}). The command reads them and writes a local folder:

  • collections/: one collection per table, and an index.ts exporting rowyCollections
  • rowy-scripts/: the derivative, action, default value, formula, extension and webhook code Rowy ran, to port
  • MIGRATION_REPORT.md: what each column became and what is left to do, plus roles, extensions and webhooks
firecms migrate rowy --project=your-project-id [--target=cloud|self-hosted] [--out=dir] [--tables=a,b] [--force]
firecms migrate rowy --input=rowy-config.json   # offline

How it behaves

  • Read only. It reads Rowy's configuration and nothing else: no documents, no writes to the project.
  • No keys. It uses the person's gcloud sign-in against the Firestore REST API, so no service account key and no new dependencies.
  • No guessing. Columns Rowy did not fully describe are converted read-only and listed in the report: references without a target, files stored as { downloadURL, ref, ... }, and Connect table snapshots. Unknown types are left out. Their data stays in the document and the JSON tab (includeJsonView) shows it.
  • Secrets. Webhook auth settings are never copied. A line in a copied script that looks like a hardcoded credential is reported by file and line, never the value.
  • Rowy parity where it is cheap. Dot-path fields (_createdBy.timestamp) nest into maps. Sub-tables become subcollections. Collection group tables get collectionGroup: true. An onPreSave callback keeps writing Rowy's _createdBy / _updatedBy audit fields unless the table had auditing off.
  • --target cloud imports from @firecms/cloud, self-hosted (default) from @firecms/core.

The full column mapping is in convert.ts, and the article in the companion PR explains it for users.

Testing

  • 29 new tests in test/migrate_rowy.test.ts. They cover every Rowy column type against a fixture that follows Rowy's own types, plus output files, the secret handling, the overwrite guard and Firestore REST decoding.
  • The full CLI suite passes: 111 tests. The init e2e suite needs a fresh dist (npx vite build). The one checked in locally was from February.
  • Generated collections from the fixture type-check with strict against the @firecms/core and @firecms/cloud declarations. A deliberately broken file fails the same check.
  • Ran the built bin/firecms.js end to end with --input, and with --project against a non-existent project. That read-only request fails with a clear 403 message.

The Rowy internals it relies on were checked in Rowy's source: rowyio/rowy for paths, column config and value shapes, and Rowy Run (buildship-ai/backend) for the R-<table> function naming and what that function runs.

🤖 Generated with Claude Code

…tions

Rowy keeps every table's settings in the project's own Firestore, under
`_rowy_`. The command reads them and writes, into a local folder:

- one FireCMS collection per table, plus an index exporting `rowyCollections`
- the derivative, action, default value, formula, extension and webhook
  scripts Rowy ran, to port by hand
- MIGRATION_REPORT.md: what each column became and what is left to do

It only reads Rowy's configuration: no documents, and nothing is written to
the project. It signs in with the person's gcloud account through the
Firestore REST API, so no service account key and no new dependencies.
`--input` reads the same configuration from JSON for offline use.

Nothing is guessed. A column Rowy did not fully describe (a reference
without a target, files stored as metadata objects, linked document
snapshots) is converted read-only and listed in the report. Webhook
verification secrets are never copied, and lines in copied scripts that
look like a hardcoded credential are reported by file and line, without
the value.

`--target cloud` imports from @firecms/cloud, `--target self-hosted` (the
default) from @firecms/core. The generated files type-check against both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…caping or encoding'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@marianmoldovan
marianmoldovan merged commit 2702895 into main Nov 2, 2026
4 checks passed
@marianmoldovan
marianmoldovan deleted the feat/cli-migrate-rowy branch November 2, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants