123 lines
3.6 KiB
Go
123 lines
3.6 KiB
Go
package create
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/go-errors/errors"
|
|
"github.com/spf13/afero"
|
|
"github.com/spf13/viper"
|
|
"github.com/supabase/cli/internal/utils"
|
|
"github.com/supabase/cli/internal/utils/credentials"
|
|
"github.com/supabase/cli/internal/utils/flags"
|
|
"github.com/supabase/cli/pkg/api"
|
|
)
|
|
|
|
func Run(ctx context.Context, params api.V1CreateProjectBodyDto, fsys afero.Fs) error {
|
|
if err := promptMissingParams(ctx, ¶ms); err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := utils.GetSupabase().V1CreateAProjectWithResponse(ctx, params)
|
|
if err != nil {
|
|
return errors.Errorf("failed to create project: %w", err)
|
|
}
|
|
if resp.JSON201 == nil {
|
|
return errors.New("Unexpected error creating project: " + string(resp.Body))
|
|
}
|
|
|
|
flags.ProjectRef = resp.JSON201.Id
|
|
viper.Set("DB_PASSWORD", params.DbPass)
|
|
if err := credentials.StoreProvider.Set(flags.ProjectRef, params.DbPass); err != nil {
|
|
fmt.Fprintln(os.Stderr, "Failed to save database password:", err)
|
|
}
|
|
|
|
projectUrl := fmt.Sprintf("%s/project/%s", utils.GetSupabaseDashboardURL(), resp.JSON201.Id)
|
|
fmt.Fprintf(os.Stderr, "Created a new project %s at %s\n", utils.Aqua(resp.JSON201.Name), utils.Bold(projectUrl))
|
|
if utils.OutputFormat.Value == utils.OutputPretty {
|
|
return nil
|
|
}
|
|
|
|
return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, resp.JSON201)
|
|
}
|
|
|
|
func printKeyValue(key, value string) string {
|
|
indent := 20 - len(key)
|
|
spaces := strings.Repeat(" ", indent)
|
|
return key + ":" + spaces + value
|
|
}
|
|
|
|
func promptMissingParams(ctx context.Context, body *api.V1CreateProjectBodyDto) error {
|
|
var err error
|
|
if len(body.Name) == 0 {
|
|
if body.Name, err = promptProjectName(ctx); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
fmt.Fprintln(os.Stderr, printKeyValue("Creating project", body.Name))
|
|
}
|
|
if len(body.OrganizationId) == 0 {
|
|
if body.OrganizationId, err = promptOrgId(ctx); err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintln(os.Stderr, printKeyValue("Selected org-id", body.OrganizationId))
|
|
}
|
|
if len(body.Region) == 0 {
|
|
if body.Region, err = promptProjectRegion(ctx); err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintln(os.Stderr, printKeyValue("Selected region", string(body.Region)))
|
|
}
|
|
if len(body.DbPass) == 0 {
|
|
body.DbPass = flags.PromptPassword(os.Stdin)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func promptProjectName(ctx context.Context) (string, error) {
|
|
title := "Enter your project name: "
|
|
if name, err := utils.NewConsole().PromptText(ctx, title); err != nil {
|
|
return "", err
|
|
} else if len(name) > 0 {
|
|
return name, nil
|
|
}
|
|
return "", errors.New("project name cannot be empty")
|
|
}
|
|
|
|
func promptOrgId(ctx context.Context) (string, error) {
|
|
title := "Which organisation do you want to create the project for?"
|
|
resp, err := utils.GetSupabase().V1ListAllOrganizationsWithResponse(ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if resp.JSON200 == nil {
|
|
return "", errors.New("Unexpected error retrieving organizations: " + string(resp.Body))
|
|
}
|
|
items := make([]utils.PromptItem, len(*resp.JSON200))
|
|
for i, org := range *resp.JSON200 {
|
|
items[i] = utils.PromptItem{Summary: org.Name, Details: org.Id}
|
|
}
|
|
choice, err := utils.PromptChoice(ctx, title, items)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return choice.Details, nil
|
|
}
|
|
|
|
func promptProjectRegion(ctx context.Context) (api.V1CreateProjectBodyDtoRegion, error) {
|
|
title := "Which region do you want to host the project in?"
|
|
items := make([]utils.PromptItem, len(utils.RegionMap))
|
|
i := 0
|
|
for k, v := range utils.RegionMap {
|
|
items[i] = utils.PromptItem{Summary: k, Details: v}
|
|
i++
|
|
}
|
|
choice, err := utils.PromptChoice(ctx, title, items)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return api.V1CreateProjectBodyDtoRegion(choice.Summary), nil
|
|
}
|