github.com/supabase/cli@v1.168.1/internal/gen/types/typescript/typescript.go (about)

     1  package typescript
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/docker/docker/api/types/container"
    10  	"github.com/docker/docker/api/types/network"
    11  	"github.com/go-errors/errors"
    12  	"github.com/jackc/pgconn"
    13  	"github.com/jackc/pgx/v4"
    14  	"github.com/spf13/afero"
    15  	"github.com/supabase/cli/internal/utils"
    16  	"github.com/supabase/cli/pkg/api"
    17  )
    18  
    19  func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas []string, postgrestV9Compat bool, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
    20  	originalURL := utils.ToPostgresURL(dbConfig)
    21  	// Add default schemas if --schema flag is not specified
    22  	if len(schemas) == 0 {
    23  		schemas = utils.RemoveDuplicates(append([]string{"public"}, utils.Config.Api.Schemas...))
    24  	}
    25  	included := strings.Join(schemas, ",")
    26  
    27  	if projectId != "" {
    28  		resp, err := utils.GetSupabase().GetTypescriptTypesWithResponse(ctx, projectId, &api.GetTypescriptTypesParams{
    29  			IncludedSchemas: &included,
    30  		})
    31  		if err != nil {
    32  			return errors.Errorf("failed to get typescript types: %w", err)
    33  		}
    34  
    35  		if resp.JSON200 == nil {
    36  			return errors.New("failed to retrieve generated types: " + string(resp.Body))
    37  		}
    38  
    39  		fmt.Print(resp.JSON200.Types)
    40  		return nil
    41  	}
    42  
    43  	networkID := "host"
    44  	if utils.IsLocalDatabase(dbConfig) {
    45  		if err := utils.AssertSupabaseDbIsRunning(); err != nil {
    46  			return err
    47  		}
    48  
    49  		if strings.Contains(utils.Config.Api.Image, "v9") {
    50  			postgrestV9Compat = true
    51  		}
    52  
    53  		// Use custom network when connecting to local database
    54  		dbConfig.Host = utils.DbAliases[0]
    55  		dbConfig.Port = 5432
    56  		networkID = utils.NetId
    57  	}
    58  	// pg-meta does not set username as the default database, ie. postgres
    59  	if len(dbConfig.Database) == 0 {
    60  		dbConfig.Database = "postgres"
    61  	}
    62  
    63  	fmt.Fprintln(os.Stderr, "Connecting to", dbConfig.Host, dbConfig.Port)
    64  	escaped := utils.ToPostgresURL(dbConfig)
    65  	if require, err := isRequireSSL(ctx, originalURL, options...); err != nil {
    66  		return err
    67  	} else if require {
    68  		// node-postgres does not support sslmode=prefer
    69  		escaped += "&sslmode=require"
    70  	}
    71  
    72  	return utils.DockerRunOnceWithConfig(
    73  		ctx,
    74  		container.Config{
    75  			Image: utils.PgmetaImage,
    76  			Env: []string{
    77  				"PG_META_DB_URL=" + escaped,
    78  				"PG_META_GENERATE_TYPES=typescript",
    79  				"PG_META_GENERATE_TYPES_INCLUDED_SCHEMAS=" + included,
    80  				fmt.Sprintf("PG_META_GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS=%v", !postgrestV9Compat),
    81  			},
    82  			Cmd: []string{"node", "dist/server/server.js"},
    83  		},
    84  		container.HostConfig{
    85  			NetworkMode: container.NetworkMode(networkID),
    86  		},
    87  		network.NetworkingConfig{},
    88  		"",
    89  		os.Stdout,
    90  		os.Stderr,
    91  	)
    92  }
    93  
    94  func isRequireSSL(ctx context.Context, dbUrl string, options ...func(*pgx.ConnConfig)) (bool, error) {
    95  	conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require", options...)
    96  	if err != nil {
    97  		if strings.HasSuffix(err.Error(), "(server refused TLS connection)") {
    98  			return false, nil
    99  		}
   100  		return false, err
   101  	}
   102  	return true, conn.Close(ctx)
   103  }