migrate

package
v0.57.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package migrate reads the app/ of a Next.js project and writes the app/ of a Trilha one: the folders the convention asks for, files that compile, and a report of what each screen does. It is the mechanical half of a migration — the half that costs a lot of tokens and no thought.

What it does not do is translate JSX: the tree and the map are what is deterministic, and the screen is the work of whoever ports it.

Index

Constants

View Source
const (
	ClassForm   = "A" // form and list: no island signal, no polling
	ClassIsland = "B" // small island: polling, modal, tabs, upload
	ClassSPA    = "C" // pointer, drawing surface or editor
)

The classes, in the order the report explains them.

View Source
const (
	KindPage     = "page"
	KindLayout   = "layout"
	KindRoute    = "route"
	KindNotFound = "not-found"
	KindError    = "error"
)

The kinds of Next file that have somewhere to go here.

View Source
const (
	NoteParallel    = "parallel-route"
	NoteIntercept   = "intercepting-route"
	NoteLoading     = "loading"
	NoteTemplate    = "template"
	NoteDefault     = "default"
	NoteMiddleware  = "middleware"
	NoteRewrite     = "rewrite"
	NoteRootLayout  = "root-layout"
	NoteNestedFile  = "nested-root-file"
	NoteRenamed     = "renamed-param"
	NoteDuplicate   = "duplicate-route"
	NoteOptionalAll = "optional-catch-all"
)

Codes of Note, so the report and the tests agree on the names.

View Source
const (
	Created = "created"
	Kept    = "kept"
)

Written is the action of a file this run wrote.

Variables

This section is empty.

Functions

func Report

func Report(p Project, lang string) string

Report writes MIGRATION.md: one row per screen with what the source says about itself, and one list of everything that has no equivalent here. It is the map whoever ports the app reads — a person or an agent — so that the first question of every screen is answered before the file is opened.

lang is "en" or "pt", like the rest of the CLI.

Types

type Analysis

type Analysis struct {
	Client    bool           // 'use client' at the top
	Hooks     map[string]int // useState, useEffect, useRef...
	Endpoints []Endpoint     // what it calls
	Signals   []string       // the names below that matched
	Class     string         // A, B or C
	Why       string         // the reason for the class, in one clause
	Deps      []string       // the files it imports that were read too
	DepLines  int            // and how many lines they add to the job
}

Analysis is what a .tsx says about itself. It is read with regular expressions over the text, the way the audit reads a Go file: a TypeScript parser without external dependencies would be a project of its own, and the five questions that matter here are answered by five expressions. The rule is printed in the report so it can be argued with.

type Endpoint

type Endpoint struct {
	Method string
	Path   string
}

Endpoint is one address the screen calls, with the method it calls it with.

type File

type File struct {
	Path string // relative to the output root
	Body string
}

File is one file the migration writes.

type Note

type Note struct {
	Source string
	Code   string
	Detail string
}

Note is something the command will not translate. A note is not a failure: it is the line of the report that says a decision is somebody's to make.

type Page

type Page struct {
	Source  string   // path of the .tsx, relative to the project root
	Lines   int      // lines of the source, so a reader can size the job
	Kind    string   // KindPage, KindLayout, KindRoute...
	URL     string   // the URL it answers, spelled as Trilha spells it
	Dir     string   // folder under app/, "" for the root
	File    string   // page.go, layout.go, route.go...
	Pkg     string   // package clause of the generated file
	Params  []string // parameter names, in order
	Methods []string // handlers found in a route.ts
	Analysis
}

Page is one file of the Next app and the file that answers for it here.

type Project

type Project struct {
	Root   string // the directory that was read
	AppDir string // the app/ inside it, relative to Root
	Pages  []Page
	Notes  []Note
}

Project is what Scan found: the pages in the order the tree gives them, and everything that has no equivalent here.

func Scan

func Scan(root string) (Project, error)

Scan reads the Next project at root. It accepts the project root (with app/ or src/app/ inside it) or the app directory itself, because both are what somebody has open when they think of running this.

func (Project) Files

func (p Project) Files() []File

Files renders every page as the Go file that answers for it, in the order they were found: same tree, same bytes.

type Result

type Result struct {
	Path   string
	Action string // "created" or "kept"
}

Result is what happened to one file.

func Write

func Write(root string, p Project, force bool) ([]Result, error)

Write puts the files under root. A file that is already there is kept unless force: running the command a second time, after three screens have been ported, must not cost the three screens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL