• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / cli / 20369862521

19 Dec 2025 12:21PM UTC coverage: 56.046% (-0.2%) from 56.237%
20369862521

Pull #4604

github

web-flow
Merge ddae3156d into 1876c6601
Pull Request #4604: feat: supabase public url

1 of 1 new or added line in 1 file covered. (100.0%)

68 existing lines in 6 files now uncovered.

6813 of 12156 relevant lines covered (56.05%)

6.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/cmd/gen.go
1
package cmd
2

3
import (
4
        "encoding/json"
5
        "os"
6
        "os/signal"
7
        "strings"
8
        "time"
9

10
        env "github.com/Netflix/go-env"
11
        "github.com/go-errors/errors"
12
        "github.com/go-viper/mapstructure/v2"
13
        "github.com/golang-jwt/jwt/v5"
14
        "github.com/spf13/afero"
15
        "github.com/spf13/cobra"
16
        "github.com/supabase/cli/internal/gen/bearerjwt"
17
        "github.com/supabase/cli/internal/gen/keys"
18
        "github.com/supabase/cli/internal/gen/signingkeys"
19
        "github.com/supabase/cli/internal/gen/types"
20
        "github.com/supabase/cli/internal/utils"
21
        "github.com/supabase/cli/internal/utils/flags"
22
        "github.com/supabase/cli/pkg/config"
23
)
24

25
var (
26
        genCmd = &cobra.Command{
27
                GroupID: groupLocalDev,
28
                Use:     "gen",
29
                Short:   "Run code generation tools",
30
        }
31

32
        keyNames keys.CustomName
33

34
        genKeysCmd = &cobra.Command{
35
                Deprecated: `use "gen signing-key" instead.`,
36
                Use:        "keys",
37
                Short:      "Generate keys for preview branch",
38
                PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
×
39
                        es, err := env.EnvironToEnvSet(override)
×
40
                        if err != nil {
×
41
                                return err
×
42
                        }
×
43
                        if err := env.Unmarshal(es, &keyNames); err != nil {
×
44
                                return err
×
45
                        }
×
46
                        cmd.GroupID = groupManagementAPI
×
47
                        return cmd.Root().PersistentPreRunE(cmd, args)
×
48
                },
49
                RunE: func(cmd *cobra.Command, args []string) error {
×
50
                        format := utils.OutputFormat.Value
×
51
                        if format == utils.OutputPretty {
×
52
                                format = utils.OutputEnv
×
53
                        }
×
54
                        return keys.Run(cmd.Context(), flags.ProjectRef, format, keyNames, afero.NewOsFs())
×
55
                },
56
        }
57

58
        lang = utils.EnumFlag{
59
                Allowed: []string{
60
                        types.LangTypescript,
61
                        types.LangGo,
62
                        types.LangSwift,
63
                        types.LangPython,
64
                },
65
                Value: types.LangTypescript,
66
        }
67
        queryTimeout       time.Duration
68
        postgrestV9Compat  bool
69
        swiftAccessControl = utils.EnumFlag{
70
                Allowed: []string{
71
                        types.SwiftInternalAccessControl,
72
                        types.SwiftPublicAccessControl,
73
                },
74
                Value: types.SwiftInternalAccessControl,
75
        }
76

77
        genTypesCmd = &cobra.Command{
78
                Use:   "types",
79
                Short: "Generate types from Postgres schema",
80
                PreRunE: func(cmd *cobra.Command, args []string) error {
×
81
                        if postgrestV9Compat && !cmd.Flags().Changed("db-url") {
×
82
                                return errors.New("--postgrest-v9-compat must used together with --db-url")
×
UNCOV
83
                        }
×
84
                        // Legacy commands specify language using arg, eg. gen types typescript
85
                        if len(args) > 0 && args[0] != types.LangTypescript && !cmd.Flags().Changed("lang") {
×
86
                                return errors.New("use --lang flag to specify the typegen language")
×
87
                        }
×
UNCOV
88
                        return nil
×
89
                },
90
                RunE: func(cmd *cobra.Command, args []string) error {
×
91
                        ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt)
×
92
                        if flags.DbConfig.Host == "" {
×
93
                                // If no flag is specified, prompt for project id.
×
94
                                if err := flags.ParseProjectRef(ctx, afero.NewMemMapFs()); errors.Is(err, utils.ErrNotLinked) {
×
95
                                        return errors.New("Must specify one of --local, --linked, --project-id, or --db-url")
×
96
                                } else if err != nil {
×
97
                                        return err
×
UNCOV
98
                                }
×
99
                        }
UNCOV
100
                        return types.Run(ctx, flags.ProjectRef, flags.DbConfig, lang.Value, schema, postgrestV9Compat, swiftAccessControl.Value, queryTimeout, afero.NewOsFs())
×
101
                },
102
                Example: `  supabase gen types --local
103
  supabase gen types --linked --lang=go
104
  supabase gen types --project-id abc-def-123 --schema public --schema private
105
  supabase gen types --db-url 'postgresql://...' --schema public --schema auth`,
106
        }
107

108
        algorithm = utils.EnumFlag{
109
                Allowed: signingkeys.GetSupportedAlgorithms(),
110
                Value:   string(config.AlgES256),
111
        }
112
        appendKeys bool
113

114
        genSigningKeyCmd = &cobra.Command{
115
                Use:   "signing-key",
116
                Short: "Generate a JWT signing key",
117
                Long: `Securely generate a private JWT signing key for use in the CLI or to import in the dashboard.
118

119
Supported algorithms:
120
        ES256 - ECDSA with P-256 curve and SHA-256 (recommended)
121
        RS256 - RSA with SHA-256
122
`,
123
                RunE: func(cmd *cobra.Command, args []string) error {
×
124
                        return signingkeys.Run(cmd.Context(), algorithm.Value, appendKeys, afero.NewOsFs())
×
UNCOV
125
                },
×
126
        }
127

128
        claims   config.CustomClaims
129
        expiry   time.Time
130
        validFor time.Duration
131
        payload  string
132

133
        genJWTCmd = &cobra.Command{
134
                Use:   "bearer-jwt",
135
                Short: "Generate a Bearer Auth JWT for accessing Data API",
136
                Args:  cobra.NoArgs,
137
                RunE: func(cmd *cobra.Command, args []string) error {
×
138
                        custom := jwt.MapClaims{}
×
139
                        if err := parseClaims(custom); err != nil {
×
140
                                return err
×
141
                        }
×
UNCOV
142
                        return bearerjwt.Run(cmd.Context(), custom, os.Stdout, afero.NewOsFs())
×
143
                },
144
        }
145
)
146

147
func init() {
×
148
        typeFlags := genTypesCmd.Flags()
×
149
        typeFlags.Bool("local", false, "Generate types from the local dev database.")
×
150
        typeFlags.Bool("linked", false, "Generate types from the linked project.")
×
151
        typeFlags.String("db-url", "", "Generate types from a database url.")
×
152
        typeFlags.StringVar(&flags.ProjectRef, "project-id", "", "Generate types from a project ID.")
×
153
        genTypesCmd.MarkFlagsMutuallyExclusive("local", "linked", "project-id", "db-url")
×
154
        typeFlags.Var(&lang, "lang", "Output language of the generated types.")
×
155
        typeFlags.StringSliceVarP(&schema, "schema", "s", []string{}, "Comma separated list of schema to include.")
×
156
        // Direct connection only flags
×
157
        typeFlags.Var(&swiftAccessControl, "swift-access-control", "Access control for Swift generated types.")
×
158
        genTypesCmd.MarkFlagsMutuallyExclusive("linked", "project-id", "swift-access-control")
×
159
        typeFlags.BoolVar(&postgrestV9Compat, "postgrest-v9-compat", false, "Generate types compatible with PostgREST v9 and below.")
×
160
        genTypesCmd.MarkFlagsMutuallyExclusive("linked", "project-id", "postgrest-v9-compat")
×
161
        typeFlags.DurationVar(&queryTimeout, "query-timeout", time.Second*15, "Maximum timeout allowed for the database query.")
×
162
        genTypesCmd.MarkFlagsMutuallyExclusive("linked", "project-id", "query-timeout")
×
163
        genCmd.AddCommand(genTypesCmd)
×
164
        keyFlags := genKeysCmd.Flags()
×
165
        keyFlags.StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.")
×
166
        keyFlags.StringSliceVar(&override, "override-name", []string{}, "Override specific variable names.")
×
167
        genCmd.AddCommand(genKeysCmd)
×
168
        signingKeyFlags := genSigningKeyCmd.Flags()
×
169
        signingKeyFlags.Var(&algorithm, "algorithm", "Algorithm for signing key generation.")
×
170
        signingKeyFlags.BoolVar(&appendKeys, "append", false, "Append new key to existing keys file instead of overwriting.")
×
171
        genCmd.AddCommand(genSigningKeyCmd)
×
172
        tokenFlags := genJWTCmd.Flags()
×
173
        tokenFlags.StringVar(&claims.Role, "role", "", "Postgres role to use.")
×
174
        cobra.CheckErr(genJWTCmd.MarkFlagRequired("role"))
×
175
        tokenFlags.StringVar(&claims.Subject, "sub", "", "User ID to impersonate.")
×
176
        genJWTCmd.Flag("sub").DefValue = "anonymous"
×
177
        tokenFlags.TimeVar(&expiry, "exp", time.Time{}, []string{time.RFC3339}, "Expiry timestamp for this token.")
×
178
        tokenFlags.DurationVar(&validFor, "valid-for", time.Minute*30, "Validity duration for this token.")
×
179
        tokenFlags.StringVar(&payload, "payload", "{}", "Custom claims in JSON format.")
×
180
        genCmd.AddCommand(genJWTCmd)
×
181
        rootCmd.AddCommand(genCmd)
×
UNCOV
182
}
×
183

184
func parseClaims(custom jwt.MapClaims) error {
×
185
        // Initialise default claims
×
186
        now := time.Now()
×
187
        if expiry.IsZero() {
×
188
                expiry = now.Add(validFor)
×
189
        } else {
×
190
                now = expiry.Add(-validFor)
×
191
        }
×
192
        claims.IssuedAt = jwt.NewNumericDate(now)
×
193
        claims.ExpiresAt = jwt.NewNumericDate(expiry)
×
194
        // Set is_anonymous = true for authenticated role without explicit user ID
×
195
        if strings.EqualFold(claims.Role, "authenticated") && len(claims.Subject) == 0 {
×
196
                claims.IsAnon = true
×
UNCOV
197
        }
×
198
        // Override with custom claims
199
        if dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
×
200
                TagName: "json",
×
201
                Squash:  true,
×
202
                Result:  &custom,
×
203
        }); err != nil {
×
204
                return errors.Errorf("failed to init decoder: %w", err)
×
205
        } else if err := dec.Decode(claims); err != nil {
×
206
                return errors.Errorf("failed to decode claims: %w", err)
×
207
        }
×
208
        if err := json.Unmarshal([]byte(payload), &custom); err != nil {
×
209
                return errors.Errorf("failed to parse payload: %w", err)
×
210
        }
×
UNCOV
211
        return nil
×
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc