mirror of https://github.com/coder/coder.git
chore: support external types in typescript codegen (#9633)
* chore: support external types in typescript codegen * fix enums on external packages * Support clibase.struct * Add regexp * Make gen with updated generator
This commit is contained in:
parent
641bf272ed
commit
18c34ee456
|
@ -409,9 +409,6 @@ func DefaultCacheDir() string {
|
|||
}
|
||||
|
||||
// DeploymentConfig contains both the deployment values and how they're set.
|
||||
//
|
||||
// @typescript-ignore DeploymentConfig
|
||||
// apitypings doesn't know how to generate the OptionSet... yet.
|
||||
type DeploymentConfig struct {
|
||||
Values *DeploymentValues `json:"config,omitempty"`
|
||||
Options clibase.OptionSet `json:"options,omitempty"`
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/fatih/structtag"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/tools/go/packages"
|
||||
|
@ -26,17 +27,35 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// baseDirs are the directories to introspect for types to generate.
|
||||
baseDirs = [...]string{"./codersdk", "./coderd/healthcheck", "./coderd/healthcheck/derphealth"}
|
||||
indent = " "
|
||||
// externalTypes are types that are not in the baseDirs, but we want to
|
||||
// support. These are usually types that are used in the baseDirs.
|
||||
// Do not include things like "Database", as that would break the idea
|
||||
// of splitting db and api types.
|
||||
// Only include dirs that are client facing packages.
|
||||
externalTypeDirs = [...]string{"./cli/clibase"}
|
||||
indent = " "
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
log := slog.Make(sloghuman.Sink(os.Stderr))
|
||||
|
||||
external := []*Generator{}
|
||||
for _, dir := range externalTypeDirs {
|
||||
extGen, err := ParseDirectory(ctx, log, dir)
|
||||
if err != nil {
|
||||
log.Fatal(ctx, fmt.Sprintf("parse external directory %s: %s", dir, err.Error()))
|
||||
}
|
||||
extGen.onlyOptIn = true
|
||||
external = append(external, extGen)
|
||||
}
|
||||
|
||||
_, _ = fmt.Print("// Code generated by 'make site/src/api/typesGenerated.ts'. DO NOT EDIT.\n\n")
|
||||
for _, baseDir := range baseDirs {
|
||||
_, _ = fmt.Printf("// The code below is generated from %s.\n\n", strings.TrimPrefix(baseDir, "./"))
|
||||
output, err := Generate(baseDir)
|
||||
output, err := Generate(baseDir, external...)
|
||||
if err != nil {
|
||||
log.Fatal(ctx, err.Error())
|
||||
}
|
||||
|
@ -44,18 +63,40 @@ func main() {
|
|||
// Just cat the output to a file to capture it
|
||||
_, _ = fmt.Print(output, "\n\n")
|
||||
}
|
||||
|
||||
for i, ext := range external {
|
||||
var ts *TypescriptTypes
|
||||
for {
|
||||
var err error
|
||||
start := len(ext.allowList)
|
||||
ts, err = ext.generateAll()
|
||||
if err != nil {
|
||||
log.Fatal(ctx, fmt.Sprintf("generate external: %s", err.Error()))
|
||||
}
|
||||
if len(ext.allowList) != start {
|
||||
// This is so dumb, but basically the allowList can grow, and if
|
||||
// it does, we need to regenerate.
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
dir := externalTypeDirs[i]
|
||||
_, _ = fmt.Printf("// The code below is generated from %s.\n\n", strings.TrimPrefix(dir, "./"))
|
||||
_, _ = fmt.Print(ts.String(), "\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
func Generate(directory string) (string, error) {
|
||||
func Generate(directory string, externals ...*Generator) (string, error) {
|
||||
ctx := context.Background()
|
||||
log := slog.Make(sloghuman.Sink(os.Stderr))
|
||||
codeBlocks, err := GenerateFromDirectory(ctx, log, directory)
|
||||
gen, err := GenerateFromDirectory(ctx, log, directory, externals...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Just cat the output to a file to capture it
|
||||
return codeBlocks.String(), nil
|
||||
return gen.cachedResult.String(), nil
|
||||
}
|
||||
|
||||
// TypescriptTypes holds all the code blocks created.
|
||||
|
@ -109,23 +150,34 @@ func (t TypescriptTypes) String() string {
|
|||
return strings.TrimRight(s.String(), "\n")
|
||||
}
|
||||
|
||||
// GenerateFromDirectory will return all the typescript code blocks for a directory
|
||||
func GenerateFromDirectory(ctx context.Context, log slog.Logger, directory string) (*TypescriptTypes, error) {
|
||||
g := Generator{
|
||||
log: log,
|
||||
builtins: make(map[string]string),
|
||||
func ParseDirectory(ctx context.Context, log slog.Logger, directory string, externals ...*Generator) (*Generator, error) {
|
||||
g := &Generator{
|
||||
log: log,
|
||||
builtins: make(map[string]string),
|
||||
externals: externals,
|
||||
}
|
||||
err := g.parsePackage(ctx, directory)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("parse package %q: %w", directory, err)
|
||||
}
|
||||
|
||||
codeBlocks, err := g.generateAll()
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// GenerateFromDirectory will return all the typescript code blocks for a directory
|
||||
func GenerateFromDirectory(ctx context.Context, log slog.Logger, directory string, externals ...*Generator) (*Generator, error) {
|
||||
g, err := ParseDirectory(ctx, log, directory, externals...)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("parse package %q: %w", directory, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codeBlocks, nil
|
||||
codeBlocks, err := g.generateAll()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("generate package %q: %w", directory, err)
|
||||
}
|
||||
g.cachedResult = codeBlocks
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
type Generator struct {
|
||||
|
@ -133,6 +185,16 @@ type Generator struct {
|
|||
pkg *packages.Package
|
||||
log slog.Logger
|
||||
|
||||
// allowList if set only generates types in the allow list.
|
||||
// This is kinda a hack to get around the fact that external types
|
||||
// only should generate referenced types, and multiple packages can
|
||||
// reference the same external types.
|
||||
onlyOptIn bool
|
||||
allowList []string
|
||||
|
||||
// externals are other packages referenced. Optional
|
||||
externals []*Generator
|
||||
|
||||
// builtins is kinda a hack to get around the fact that using builtin
|
||||
// generic constraints is common. We want to support them even though
|
||||
// they are external to our package.
|
||||
|
@ -141,6 +203,8 @@ type Generator struct {
|
|||
// cannot be implemented in go. So they are a first class thing that we just
|
||||
// have to make a static string for ¯\_(ツ)_/¯
|
||||
builtins map[string]string
|
||||
|
||||
cachedResult *TypescriptTypes
|
||||
}
|
||||
|
||||
// parsePackage takes a list of patterns such as a directory, and parses them.
|
||||
|
@ -180,6 +244,10 @@ func (g *Generator) generateAll() (*TypescriptTypes, error) {
|
|||
AllowedTypes: make(map[string]struct{}),
|
||||
}
|
||||
|
||||
for _, a := range g.allowList {
|
||||
m.AllowedTypes[strings.TrimSpace(a)] = struct{}{}
|
||||
}
|
||||
|
||||
// Look for comments that indicate to ignore a type for typescript generation.
|
||||
ignoreRegex := regexp.MustCompile("@typescript-ignore[:]?(?P<ignored_types>.*)")
|
||||
for _, file := range g.pkg.Syntax {
|
||||
|
@ -303,11 +371,16 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
}
|
||||
|
||||
// If we have allowed types, only allow those to be generated.
|
||||
if _, ok := m.AllowedTypes[obj.Name()]; len(m.AllowedTypes) > 0 && !ok {
|
||||
return nil
|
||||
if _, ok := m.AllowedTypes[obj.Name()]; (len(m.AllowedTypes) > 0 || g.onlyOptIn) && !ok {
|
||||
// Allow constants to pass through, they are only included if the enum
|
||||
// is allowed.
|
||||
_, ok := obj.(*types.Const)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
objName := objName(obj)
|
||||
objectName := objName(obj)
|
||||
|
||||
switch obj := obj.(type) {
|
||||
// All named types are type declarations
|
||||
|
@ -322,13 +395,13 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
// Structs are obvious.
|
||||
codeBlock, err := g.buildStruct(obj, underNamed)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("generate %q: %w", objName, err)
|
||||
return xerrors.Errorf("generate %q: %w", objectName, err)
|
||||
}
|
||||
m.Structs[objName] = codeBlock
|
||||
m.Structs[objectName] = codeBlock
|
||||
case *types.Basic:
|
||||
// type <Name> string
|
||||
// These are enums. Store to expand later.
|
||||
m.Enums[objName] = obj
|
||||
m.Enums[objectName] = obj
|
||||
case *types.Map, *types.Array, *types.Slice:
|
||||
// Declared maps that are not structs are still valid codersdk objects.
|
||||
// Handle them custom by calling 'typescriptType' directly instead of
|
||||
|
@ -337,7 +410,7 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
// These are **NOT** enums, as a map in Go would never be used for an enum.
|
||||
ts, err := g.typescriptType(obj.Type().Underlying())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("(map) generate %q: %w", objName, err)
|
||||
return xerrors.Errorf("(map) generate %q: %w", objectName, err)
|
||||
}
|
||||
|
||||
var str strings.Builder
|
||||
|
@ -347,8 +420,8 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
_, _ = str.WriteRune('\n')
|
||||
}
|
||||
// Use similar output syntax to enums.
|
||||
_, _ = str.WriteString(fmt.Sprintf("export type %s = %s\n", objName, ts.ValueType))
|
||||
m.Structs[objName] = str.String()
|
||||
_, _ = str.WriteString(fmt.Sprintf("export type %s = %s\n", objectName, ts.ValueType))
|
||||
m.Structs[objectName] = str.String()
|
||||
case *types.Interface:
|
||||
// Interfaces are used as generics. Non-generic interfaces are
|
||||
// not supported.
|
||||
|
@ -366,9 +439,9 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
|
||||
block, err := g.buildUnion(obj, union)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("generate union %q: %w", objName, err)
|
||||
return xerrors.Errorf("generate union %q: %w", objectName, err)
|
||||
}
|
||||
m.Generics[objName] = block
|
||||
m.Generics[objectName] = block
|
||||
}
|
||||
case *types.Signature:
|
||||
// Ignore named functions.
|
||||
|
@ -383,13 +456,13 @@ func (g *Generator) generateOne(m *Maps, obj types.Object) error {
|
|||
case *types.Const:
|
||||
// We only care about named constant types, since they are enums
|
||||
if named, ok := obj.Type().(*types.Named); ok {
|
||||
name := named.Obj().Name()
|
||||
m.EnumConsts[name] = append(m.EnumConsts[name], obj)
|
||||
enumObjName := objName(named.Obj())
|
||||
m.EnumConsts[enumObjName] = append(m.EnumConsts[enumObjName], obj)
|
||||
}
|
||||
case *types.Func:
|
||||
// Noop
|
||||
default:
|
||||
_, _ = fmt.Println(objName)
|
||||
_, _ = fmt.Println(objectName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -751,9 +824,22 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
n := ty
|
||||
|
||||
// These are external named types that we handle uniquely.
|
||||
// This is unfortunate, but our current code assumes all defined
|
||||
// types are enums, but these are really just basic primitives.
|
||||
// We would need to add more logic to determine this, but for now
|
||||
// just hard code them.
|
||||
switch n.String() {
|
||||
case "github.com/coder/coder/v2/cli/clibase.Regexp":
|
||||
return TypescriptType{ValueType: "string"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.HostPort":
|
||||
// Custom marshal json to be a string
|
||||
return TypescriptType{ValueType: "string"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.StringArray":
|
||||
return TypescriptType{ValueType: "string[]"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.String":
|
||||
return TypescriptType{ValueType: "string"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.YAMLConfigPath":
|
||||
return TypescriptType{ValueType: "string"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.Strings":
|
||||
return TypescriptType{ValueType: "string[]"}, nil
|
||||
case "github.com/coder/coder/v2/cli/clibase.Int64":
|
||||
|
@ -783,14 +869,42 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
return TypescriptType{ValueType: "string"}, nil
|
||||
}
|
||||
|
||||
// Some hard codes are a bit trickier.
|
||||
//nolint:gocritic,revive // I prefer the switch for extensibility later.
|
||||
switch {
|
||||
// Struct is a generic, so the type has generic constraints in the string.
|
||||
case regexp.MustCompile(`github\.com/coder/coder/v2/cli/clibase.Struct\[.*\]`).MatchString(n.String()):
|
||||
// The marshal json just marshals the underlying value.
|
||||
str, ok := ty.Underlying().(*types.Struct)
|
||||
if ok {
|
||||
return g.typescriptType(str.Field(0).Type())
|
||||
}
|
||||
}
|
||||
|
||||
// Then see if the type is defined elsewhere. If it is, we can just
|
||||
// put the objName as it will be defined in the typescript codeblock
|
||||
// we generate.
|
||||
objName := objName(n.Obj())
|
||||
genericName := ""
|
||||
genericTypes := make(map[string]string)
|
||||
pkgName := n.Obj().Pkg().Name()
|
||||
if obj := g.pkg.Types.Scope().Lookup(n.Obj().Name()); g.pkg.Name == pkgName && obj != nil {
|
||||
|
||||
obj, objGen, local := g.lookupNamedReference(n)
|
||||
if obj != nil {
|
||||
if g.onlyOptIn && !slices.Contains(g.allowList, n.Obj().Name()) {
|
||||
// This is kludgy, but if we are an external package,
|
||||
// we need to also include dependencies. There is no
|
||||
// good way to return all extra types we need to include,
|
||||
// so just add them to the allow list and hope the caller notices
|
||||
// the slice grew...
|
||||
g.allowList = append(g.allowList, n.Obj().Name())
|
||||
}
|
||||
if !local {
|
||||
objGen.allowList = append(objGen.allowList, n.Obj().Name())
|
||||
g.log.Debug(context.Background(), "found external type",
|
||||
"name", objName,
|
||||
"ext_pkg", objGen.pkg.String(),
|
||||
)
|
||||
}
|
||||
// Sweet! Using other typescript types as fields. This could be an
|
||||
// enum or another struct
|
||||
if args := n.TypeArgs(); args != nil && args.Len() > 0 {
|
||||
|
@ -817,10 +931,13 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
genericName = objName + fmt.Sprintf("<%s>", strings.Join(genericNames, ", "))
|
||||
objName += fmt.Sprintf("<%s>", strings.Join(genericConstraints, ", "))
|
||||
}
|
||||
|
||||
cmt := ""
|
||||
return TypescriptType{
|
||||
GenericTypes: genericTypes,
|
||||
GenericValue: genericName,
|
||||
ValueType: objName,
|
||||
GenericTypes: genericTypes,
|
||||
GenericValue: genericName,
|
||||
ValueType: objName,
|
||||
AboveTypeLine: cmt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -842,7 +959,10 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
if err != nil {
|
||||
return TypescriptType{}, xerrors.Errorf("named underlying: %w", err)
|
||||
}
|
||||
ts.AboveTypeLine = indentedComment(fmt.Sprintf("This is likely an enum in an external package (%q)", n.String()))
|
||||
if ts.AboveTypeLine == "" {
|
||||
// If no comment exists explaining where this type comes from, add one.
|
||||
ts.AboveTypeLine = indentedComment(fmt.Sprintf("This is likely an enum in an external package (%q)", n.String()))
|
||||
}
|
||||
return ts, nil
|
||||
case *types.Pointer:
|
||||
// Dereference pointers.
|
||||
|
@ -868,6 +988,20 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Do support "Stringer" interfaces, they likely can get string
|
||||
// marshalled.
|
||||
for i := 0; i < intf.NumMethods(); i++ {
|
||||
meth := intf.Method(i)
|
||||
if meth.Name() == "String" {
|
||||
return TypescriptType{
|
||||
ValueType: "string",
|
||||
AboveTypeLine: indentedComment("actual value is an interface that implements 'String()'"),
|
||||
Optional: false,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// All complex interfaces should be named. So if we get here, that means
|
||||
// we are using anonymous interfaces. Which is just weird and not supported.
|
||||
// Example:
|
||||
|
@ -928,6 +1062,22 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
|
|||
return TypescriptType{}, xerrors.Errorf("unknown type: %s", ty.String())
|
||||
}
|
||||
|
||||
func (g *Generator) lookupNamedReference(n *types.Named) (obj types.Object, generator *Generator, local bool) {
|
||||
pkgName := n.Obj().Pkg().Name()
|
||||
|
||||
if obj := g.pkg.Types.Scope().Lookup(n.Obj().Name()); g.pkg.Name == pkgName && obj != nil {
|
||||
return obj, g, true
|
||||
}
|
||||
|
||||
for _, ext := range g.externals {
|
||||
if obj := ext.pkg.Types.Scope().Lookup(n.Obj().Name()); ext.pkg.Name == pkgName && obj != nil {
|
||||
return obj, ext, false
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
// isBuiltIn returns the string for a builtin type that we want to support
|
||||
// if the name is a reserved builtin type. This is for types like 'comparable'.
|
||||
// These types are not implemented in golang, so we just have to hardcode it.
|
||||
|
|
|
@ -323,7 +323,6 @@ export interface DERPServerConfig {
|
|||
readonly region_id: number;
|
||||
readonly region_code: string;
|
||||
readonly region_name: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly stun_addresses: string[];
|
||||
readonly relay_url: string;
|
||||
}
|
||||
|
@ -335,6 +334,12 @@ export interface DangerousConfig {
|
|||
readonly allow_all_cors: boolean;
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
export interface DeploymentConfig {
|
||||
readonly config?: DeploymentValues;
|
||||
readonly options?: ClibaseOptionSet;
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
export interface DeploymentStats {
|
||||
readonly aggregated_from: string;
|
||||
|
@ -357,9 +362,7 @@ export interface DeploymentValues {
|
|||
readonly derp?: DERP;
|
||||
readonly prometheus?: PrometheusConfig;
|
||||
readonly pprof?: PprofConfig;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly proxy_trusted_headers?: string[];
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly proxy_trusted_origins?: string[];
|
||||
readonly cache_directory?: string;
|
||||
readonly in_memory_database?: boolean;
|
||||
|
@ -371,7 +374,6 @@ export interface DeploymentValues {
|
|||
readonly trace?: TraceConfig;
|
||||
readonly secure_auth_cookie?: boolean;
|
||||
readonly strict_transport_security?: number;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly strict_transport_security_options?: string[];
|
||||
readonly ssh_keygen_algorithm?: string;
|
||||
readonly metrics_cache_refresh_interval?: number;
|
||||
|
@ -379,11 +381,9 @@ export interface DeploymentValues {
|
|||
readonly agent_fallback_troubleshooting_url?: string;
|
||||
readonly browser_only?: boolean;
|
||||
readonly scim_api_key?: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly external_token_encryption_keys?: string[];
|
||||
readonly provisioner?: ProvisionerConfig;
|
||||
readonly rate_limit?: RateLimitConfig;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly experiments?: string[];
|
||||
readonly update_check?: boolean;
|
||||
readonly max_token_lifetime?: number;
|
||||
|
@ -395,21 +395,16 @@ export interface DeploymentValues {
|
|||
readonly disable_session_expiry_refresh?: boolean;
|
||||
readonly disable_password_auth?: boolean;
|
||||
readonly support?: SupportConfig;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Struct[[]github.com/coder/coder/v2/codersdk.GitAuthConfig]" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly git_auth?: any;
|
||||
readonly git_auth?: GitAuthConfig[];
|
||||
readonly config_ssh?: SSHConfig;
|
||||
readonly wgtunnel_host?: string;
|
||||
readonly disable_owner_workspace_exec?: boolean;
|
||||
readonly proxy_health_status_interval?: number;
|
||||
readonly enable_terraform_debug_mode?: boolean;
|
||||
readonly user_quiet_hours_schedule?: UserQuietHoursScheduleConfig;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.YAMLConfigPath")
|
||||
readonly config?: string;
|
||||
readonly write_config?: boolean;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.HostPort" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly address?: any;
|
||||
readonly address?: string;
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
|
@ -559,7 +554,6 @@ export interface LinkConfig {
|
|||
|
||||
// From codersdk/deployment.go
|
||||
export interface LoggingConfig {
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly log_filter: string[];
|
||||
readonly human: string;
|
||||
readonly json: string;
|
||||
|
@ -593,9 +587,7 @@ export interface OAuth2Config {
|
|||
export interface OAuth2GithubConfig {
|
||||
readonly client_id: string;
|
||||
readonly client_secret: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly allowed_orgs: string[];
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly allowed_teams: string[];
|
||||
readonly allow_signups: boolean;
|
||||
readonly allow_everyone: boolean;
|
||||
|
@ -623,31 +615,20 @@ export interface OIDCConfig {
|
|||
readonly client_secret: string;
|
||||
readonly client_key_file: string;
|
||||
readonly client_cert_file: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly email_domain: string[];
|
||||
readonly issuer_url: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly scopes: string[];
|
||||
readonly ignore_email_verified: boolean;
|
||||
readonly username_field: string;
|
||||
readonly email_field: string;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Struct[map[string]string]" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly auth_url_params: any;
|
||||
readonly auth_url_params: Record<string, string>;
|
||||
readonly ignore_user_info: boolean;
|
||||
readonly group_auto_create: boolean;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Regexp" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly group_regex_filter: any;
|
||||
readonly group_regex_filter: string;
|
||||
readonly groups_field: string;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Struct[map[string]string]" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly group_mapping: any;
|
||||
readonly group_mapping: Record<string, string>;
|
||||
readonly user_role_field: string;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Struct[map[string][]string]" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly user_role_mapping: any;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly user_role_mapping: Record<string, string[]>;
|
||||
readonly user_roles_default: string[];
|
||||
readonly sign_in_text: string;
|
||||
readonly icon_url: string;
|
||||
|
@ -705,17 +686,13 @@ export interface PatchWorkspaceProxy {
|
|||
// From codersdk/deployment.go
|
||||
export interface PprofConfig {
|
||||
readonly enable: boolean;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.HostPort" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly address: any;
|
||||
readonly address: string;
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
export interface PrometheusConfig {
|
||||
readonly enable: boolean;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.HostPort" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly address: any;
|
||||
readonly address: string;
|
||||
readonly collect_agent_stats: boolean;
|
||||
readonly collect_db_metrics: boolean;
|
||||
}
|
||||
|
@ -827,7 +804,6 @@ export interface Role {
|
|||
// From codersdk/deployment.go
|
||||
export interface SSHConfig {
|
||||
readonly DeploymentName: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly SSHConfigOptions: string[];
|
||||
}
|
||||
|
||||
|
@ -862,9 +838,7 @@ export interface SessionCountDeploymentStats {
|
|||
|
||||
// From codersdk/deployment.go
|
||||
export interface SupportConfig {
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.Struct[[]github.com/coder/coder/v2/codersdk.LinkConfig]" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly links: any;
|
||||
readonly links: LinkConfig[];
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
|
@ -875,15 +849,11 @@ export interface SwaggerConfig {
|
|||
// From codersdk/deployment.go
|
||||
export interface TLSConfig {
|
||||
readonly enable: boolean;
|
||||
// Named type "github.com/coder/coder/v2/cli/clibase.HostPort" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
|
||||
readonly address: any;
|
||||
readonly address: string;
|
||||
readonly redirect_http: boolean;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly cert_file: string[];
|
||||
readonly client_auth: string;
|
||||
readonly client_ca_file: string;
|
||||
// This is likely an enum in an external package ("github.com/coder/coder/v2/cli/clibase.StringArray")
|
||||
readonly key_file: string[];
|
||||
readonly min_version: string;
|
||||
readonly client_cert_file: string;
|
||||
|
@ -2076,3 +2046,48 @@ export interface DerphealthStunReport {
|
|||
readonly CanSTUN: boolean;
|
||||
readonly Error?: string;
|
||||
}
|
||||
|
||||
// The code below is generated from cli/clibase.
|
||||
|
||||
// From clibase/clibase.go
|
||||
export type ClibaseAnnotations = Record<string, string>;
|
||||
|
||||
// From clibase/clibase.go
|
||||
export interface ClibaseGroup {
|
||||
readonly parent?: ClibaseGroup;
|
||||
readonly name?: string;
|
||||
readonly yaml?: string;
|
||||
readonly description?: string;
|
||||
}
|
||||
|
||||
// From clibase/option.go
|
||||
export interface ClibaseOption {
|
||||
readonly name?: string;
|
||||
readonly description?: string;
|
||||
readonly required?: boolean;
|
||||
readonly flag?: string;
|
||||
readonly flag_shorthand?: string;
|
||||
readonly env?: string;
|
||||
readonly yaml?: string;
|
||||
readonly default?: string;
|
||||
// actual value is an interface that implements 'String()'
|
||||
readonly value?: string;
|
||||
readonly annotations?: ClibaseAnnotations;
|
||||
readonly group?: ClibaseGroup;
|
||||
readonly use_instead?: ClibaseOption[];
|
||||
readonly hidden?: boolean;
|
||||
readonly value_source?: ClibaseValueSource;
|
||||
}
|
||||
|
||||
// From clibase/option.go
|
||||
export type ClibaseOptionSet = ClibaseOption[];
|
||||
|
||||
// From clibase/option.go
|
||||
export type ClibaseValueSource = "" | "default" | "env" | "flag" | "yaml";
|
||||
export const ClibaseValueSources: ClibaseValueSource[] = [
|
||||
"",
|
||||
"default",
|
||||
"env",
|
||||
"flag",
|
||||
"yaml",
|
||||
];
|
||||
|
|
|
@ -12,6 +12,15 @@ const meta: Meta<typeof GitAuthSettingsPageView> = {
|
|||
type: "GitHub",
|
||||
client_id: "client_id",
|
||||
regex: "regex",
|
||||
auth_url: "",
|
||||
token_url: "",
|
||||
validate_url: "",
|
||||
app_install_url: "https://github.com/apps/coder/installations/new",
|
||||
app_installations_url: "",
|
||||
no_refresh: false,
|
||||
scopes: [],
|
||||
device_flow: true,
|
||||
device_code_url: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -56,7 +56,7 @@ export const GitAuthSettingsPageView = ({
|
|||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{((config.git_auth === null || config.git_auth.length === 0) && (
|
||||
{((config.git_auth === null || config.git_auth?.length === 0) && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<div className={styles.empty}>
|
||||
|
@ -65,7 +65,7 @@ export const GitAuthSettingsPageView = ({
|
|||
</TableCell>
|
||||
</TableRow>
|
||||
)) ||
|
||||
config.git_auth.map((git: GitAuthConfig) => {
|
||||
config.git_auth?.map((git: GitAuthConfig) => {
|
||||
const name = git.id || git.type;
|
||||
return (
|
||||
<TableRow key={name}>
|
||||
|
|
Loading…
Reference in New Issue