Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1,093 changes: 644 additions & 449 deletions CONTEXT.md

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# GoFast CLI

Building blocks for Go.
Generate production-ready Go apps with ConnectRPC, SvelteKit, and PostgreSQL.
Generate production-ready Go apps with ConnectRPC, SvelteKit or TanStack Start, and PostgreSQL.

This repository contains two CLI tools:
- **`gof`** - v2 CLI (current)
Expand All @@ -19,7 +19,7 @@ The v2 CLI generates full-stack Go applications with:
- Go backend with ConnectRPC transport
- PostgreSQL database with SQLC
- OAuth authentication (GitHub, Google, Phone)
- Optional Svelte frontend
- Optional Svelte or TanStack frontend
- Optional integrations (Stripe, S3, Postmark)

Visit [gofast.live](https://gofast.live) for more details and features.
Expand Down Expand Up @@ -73,6 +73,7 @@ make start
| `gof init <name>` | Create new project |
| `gof model <name> [cols...]` | Generate CRUD model |
| `gof client svelte` | Add Svelte frontend |
| `gof client tanstack` | Add TanStack frontend |
| `gof add stripe` | Add Stripe payments |
| `gof add s3` | Add S3 file storage |
| `gof add postmark` | Add Postmark email |
Expand Down Expand Up @@ -105,6 +106,7 @@ gof model comment content:string

# Add frontend
gof client svelte
# or: gof client tanstack

# Add payments
gof add stripe
Expand All @@ -115,21 +117,23 @@ gof infra
# Generate code
make sql && make gen && make format && make migrate

# Run with client
make startc
# Run with Svelte
make starts

# Run with client + monitoring (Grafana, Alloy, Loki, Tempo, Prometheus)
make startcm
# Run with TanStack
make startt
```

### Generated Project Commands

| Command | Description |
|---------|-------------|
| `make start` | Start backend services |
| `make startc` | Start with Svelte client |
| `make starts` | Start with Svelte client |
| `make startt` | Start with TanStack client |
| `make startm` | Start with monitoring (Grafana, Alloy, Loki, Tempo, Prometheus) |
| `make startcm` | Start with client + monitoring |
| `make startsm` | Start with Svelte client + monitoring |
| `make starttm` | Start with TanStack client + monitoring |
| `make sql` | Regenerate SQLC queries |
| `make gen` | Regenerate proto code |
| `make migrate` | Apply database migrations |
Expand Down
4 changes: 4 additions & 0 deletions cmd/gof/auth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func checkConfig(email string, apiKey string) tea.Cmd {
}

func CheckAuthentication() (string, string, error) {
if os.Getenv("TEST") == "true" {
return "test@gofast.local", "test-api-key", nil
}

path, err := os.UserConfigDir()
if err != nil {
return "", "", err
Expand Down
73 changes: 73 additions & 0 deletions cmd/gof/clients/clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package clients

import "github.com/gofast-live/gofast-cli/v2/cmd/gof/config"

const (
Svelte = "svelte"
Tanstack = "tanstack"
)

type Spec struct {
Name string
DisplayName string
ServiceDir string
ComposeFile string
Port string
PaymentsRouteSubpath string
FilesRouteSubpath string
EmailsRouteSubpath string
}

var specs = map[string]Spec{
Svelte: {
Name: Svelte,
DisplayName: "Svelte",
ServiceDir: "service-svelte",
ComposeFile: "docker-compose.svelte.yml",
Port: "3000",
PaymentsRouteSubpath: "src/routes/(app)/payments",
FilesRouteSubpath: "src/routes/(app)/files",
EmailsRouteSubpath: "src/routes/(app)/emails",
},
Tanstack: {
Name: Tanstack,
DisplayName: "TanStack",
ServiceDir: "service-tanstack",
ComposeFile: "docker-compose.tanstack.yml",
Port: "3000",
PaymentsRouteSubpath: "src/routes/_layout/payments",
FilesRouteSubpath: "src/routes/_layout/files.tsx",
EmailsRouteSubpath: "src/routes/_layout/emails.tsx",
},
}

func SpecFor(name string) (Spec, bool) {
spec, ok := specs[name]
return spec, ok
}

func All() []Spec {
return []Spec{
specs[Svelte],
specs[Tanstack],
}
}

func Enabled(cfg *config.Config) []Spec {
if cfg == nil {
return nil
}

var enabled []Spec
for _, service := range cfg.Services {
spec, ok := SpecFor(service.Name)
if ok {
enabled = append(enabled, spec)
}
}
return enabled
}

func HasAny(cfg *config.Config) bool {
return len(Enabled(cfg)) > 0
}
40 changes: 34 additions & 6 deletions cmd/gof/cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os/exec"

"github.com/gofast-live/gofast-cli/v2/cmd/gof/auth"
"github.com/gofast-live/gofast-cli/v2/cmd/gof/clients"
"github.com/gofast-live/gofast-cli/v2/cmd/gof/config"
"github.com/gofast-live/gofast-cli/v2/cmd/gof/integrations"
"github.com/spf13/cobra"
Expand All @@ -16,6 +17,21 @@ func init() {
addCmd.AddCommand(addPostmarkCmd)
}

func formatEnabledClients() error {
cfg, err := config.ParseConfig()
if err != nil {
return err
}

for _, client := range clients.Enabled(cfg) {
if err := formatClientProject(client.Name); err != nil {
return err
}
}

return nil
}

var addCmd = &cobra.Command{
Use: "add",
Short: "Add optional features to the project",
Expand Down Expand Up @@ -72,12 +88,16 @@ After running this command:
cmd.Printf("Error updating config: %v\n", err)
return
}
if err := formatEnabledClients(); err != nil {
cmd.Printf("Error formatting client after Stripe add: %v\n", err)
return
}

cmd.Println("")
cmd.Println(config.SuccessStyle.Render("Stripe integration added successfully!"))
cmd.Println("")
if config.IsSvelte() {
cmd.Println("Add this route to your navigation:")
if cfg, err := config.ParseConfig(); err == nil && clients.HasAny(cfg) {
cmd.Println("Add this route to your client navigation:")
cmd.Printf(" %s\n", config.SuccessStyle.Render("/payments"))
cmd.Println("")
}
Expand Down Expand Up @@ -148,12 +168,16 @@ After running this command:
cmd.Printf("Error updating config: %v\n", err)
return
}
if err := formatEnabledClients(); err != nil {
cmd.Printf("Error formatting client after S3 add: %v\n", err)
return
}

cmd.Println("")
cmd.Println(config.SuccessStyle.Render("S3 integration added successfully!"))
cmd.Println("")
if config.IsSvelte() {
cmd.Println("Add this route to your navigation:")
if cfg, err := config.ParseConfig(); err == nil && clients.HasAny(cfg) {
cmd.Println("Add this route to your client navigation:")
cmd.Printf(" %s\n", config.SuccessStyle.Render("/files"))
cmd.Println("")
}
Expand Down Expand Up @@ -223,12 +247,16 @@ After running this command:
cmd.Printf("Error updating config: %v\n", err)
return
}
if err := formatEnabledClients(); err != nil {
cmd.Printf("Error formatting client after Postmark add: %v\n", err)
return
}

cmd.Println("")
cmd.Println(config.SuccessStyle.Render("Postmark integration added successfully!"))
cmd.Println("")
if config.IsSvelte() {
cmd.Println("Add this route to your navigation:")
if cfg, err := config.ParseConfig(); err == nil && clients.HasAny(cfg) {
cmd.Println("Add this route to your client navigation:")
cmd.Printf(" %s\n", config.SuccessStyle.Render("/emails"))
cmd.Println("")
}
Expand Down
Loading
Loading