From 405ea48824ef1c361dc0c11a30665374b008c3fa Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 12:01:56 +0100 Subject: [PATCH 01/18] feat: add environment variables db schema and queries --- .../bulk_deployment_insert.sql_generated.go | 4 +- .../db/deployment_find_by_id.sql_generated.go | 5 +- go/pkg/db/deployment_insert.sql_generated.go | 11 ++-- ...es_find_by_environment_id.sql_generated.go | 51 +++++++++++++++++ go/pkg/db/models_generated.go | 56 +++++++++++++++++++ go/pkg/db/querier_generated.go | 13 ++++- go/pkg/db/queries/deployment_insert.sql | 6 +- ...nment_variables_find_by_environment_id.sql | 5 ++ go/pkg/db/schema.sql | 16 ++++++ internal/db/src/schema/deployments.ts | 4 ++ .../db/src/schema/environment_variables.ts | 12 +++- internal/db/src/schema/index.ts | 1 + 12 files changed, 166 insertions(+), 18 deletions(-) create mode 100644 go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go create mode 100644 go/pkg/db/queries/environment_variables_find_by_environment_id.sql diff --git a/go/pkg/db/bulk_deployment_insert.sql_generated.go b/go/pkg/db/bulk_deployment_insert.sql_generated.go index 771e97d7e5..ae5410b3b4 100644 --- a/go/pkg/db/bulk_deployment_insert.sql_generated.go +++ b/go/pkg/db/bulk_deployment_insert.sql_generated.go @@ -9,7 +9,7 @@ import ( ) // bulkInsertDeployment is the base query for bulk insert -const bulkInsertDeployment = `INSERT INTO ` + "`" + `deployments` + "`" + ` ( id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, runtime_config, gateway_config, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, openapi_spec, status, gateway_config, created_at, updated_at ) VALUES %s` +const bulkInsertDeployment = `INSERT INTO ` + "`" + `deployments` + "`" + ` ( id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, runtime_config, gateway_config, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, openapi_spec, secrets_config, status, created_at, updated_at ) VALUES %s` // InsertDeployments performs bulk insert in a single query func (q *BulkQueries) InsertDeployments(ctx context.Context, db DBTX, args []InsertDeploymentParams) error { @@ -42,8 +42,8 @@ func (q *BulkQueries) InsertDeployments(ctx context.Context, db DBTX, args []Ins allArgs = append(allArgs, arg.GitCommitAuthorAvatarUrl) allArgs = append(allArgs, arg.GitCommitTimestamp) allArgs = append(allArgs, arg.OpenapiSpec) + allArgs = append(allArgs, arg.SecretsConfig) allArgs = append(allArgs, arg.Status) - allArgs = append(allArgs, arg.GatewayConfig) allArgs = append(allArgs, arg.CreatedAt) allArgs = append(allArgs, arg.UpdatedAt) } diff --git a/go/pkg/db/deployment_find_by_id.sql_generated.go b/go/pkg/db/deployment_find_by_id.sql_generated.go index a413f36715..d3156b74bf 100644 --- a/go/pkg/db/deployment_find_by_id.sql_generated.go +++ b/go/pkg/db/deployment_find_by_id.sql_generated.go @@ -10,12 +10,12 @@ import ( ) const findDeploymentById = `-- name: FindDeploymentById :one -SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, status, created_at, updated_at FROM ` + "`" + `deployments` + "`" + ` WHERE id = ? +SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, secrets_config, status, created_at, updated_at FROM ` + "`" + `deployments` + "`" + ` WHERE id = ? ` // FindDeploymentById // -// SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, status, created_at, updated_at FROM `deployments` WHERE id = ? +// SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, secrets_config, status, created_at, updated_at FROM `deployments` WHERE id = ? func (q *Queries) FindDeploymentById(ctx context.Context, db DBTX, id string) (Deployment, error) { row := db.QueryRowContext(ctx, findDeploymentById, id) var i Deployment @@ -33,6 +33,7 @@ func (q *Queries) FindDeploymentById(ctx context.Context, db DBTX, id string) (D &i.RuntimeConfig, &i.GatewayConfig, &i.OpenapiSpec, + &i.SecretsConfig, &i.Status, &i.CreatedAt, &i.UpdatedAt, diff --git a/go/pkg/db/deployment_insert.sql_generated.go b/go/pkg/db/deployment_insert.sql_generated.go index 95e368905a..2d7237d6d3 100644 --- a/go/pkg/db/deployment_insert.sql_generated.go +++ b/go/pkg/db/deployment_insert.sql_generated.go @@ -24,10 +24,10 @@ INSERT INTO ` + "`" + `deployments` + "`" + ` ( git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, - git_commit_timestamp, -- Unix epoch milliseconds + git_commit_timestamp, openapi_spec, + secrets_config, status, - gateway_config, created_at, updated_at ) @@ -66,6 +66,7 @@ type InsertDeploymentParams struct { GitCommitAuthorAvatarUrl sql.NullString `db:"git_commit_author_avatar_url"` GitCommitTimestamp sql.NullInt64 `db:"git_commit_timestamp"` OpenapiSpec sql.NullString `db:"openapi_spec"` + SecretsConfig []byte `db:"secrets_config"` Status DeploymentsStatus `db:"status"` CreatedAt int64 `db:"created_at"` UpdatedAt sql.NullInt64 `db:"updated_at"` @@ -85,10 +86,10 @@ type InsertDeploymentParams struct { // git_commit_message, // git_commit_author_handle, // git_commit_author_avatar_url, -// git_commit_timestamp, -- Unix epoch milliseconds +// git_commit_timestamp, // openapi_spec, +// secrets_config, // status, -// gateway_config, // created_at, // updated_at // ) @@ -126,8 +127,8 @@ func (q *Queries) InsertDeployment(ctx context.Context, db DBTX, arg InsertDeplo arg.GitCommitAuthorAvatarUrl, arg.GitCommitTimestamp, arg.OpenapiSpec, + arg.SecretsConfig, arg.Status, - arg.GatewayConfig, arg.CreatedAt, arg.UpdatedAt, ) diff --git a/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go b/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go new file mode 100644 index 0000000000..45953ba266 --- /dev/null +++ b/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go @@ -0,0 +1,51 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.29.0 +// source: environment_variables_find_by_environment_id.sql + +package db + +import ( + "context" +) + +const findEnvironmentVariablesByEnvironmentId = `-- name: FindEnvironmentVariablesByEnvironmentId :many +SELECT ` + "`" + `key` + "`" + `, value +FROM environment_variables +WHERE environment_id = ? + AND deleted_at IS NULL +` + +type FindEnvironmentVariablesByEnvironmentIdRow struct { + Key string `db:"key"` + Value string `db:"value"` +} + +// FindEnvironmentVariablesByEnvironmentId +// +// SELECT `key`, value +// FROM environment_variables +// WHERE environment_id = ? +// AND deleted_at IS NULL +func (q *Queries) FindEnvironmentVariablesByEnvironmentId(ctx context.Context, db DBTX, environmentID string) ([]FindEnvironmentVariablesByEnvironmentIdRow, error) { + rows, err := db.QueryContext(ctx, findEnvironmentVariablesByEnvironmentId, environmentID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FindEnvironmentVariablesByEnvironmentIdRow + for rows.Next() { + var i FindEnvironmentVariablesByEnvironmentIdRow + if err := rows.Scan(&i.Key, &i.Value); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/go/pkg/db/models_generated.go b/go/pkg/db/models_generated.go index 231a63474b..5b3416d198 100644 --- a/go/pkg/db/models_generated.go +++ b/go/pkg/db/models_generated.go @@ -278,6 +278,48 @@ func (ns NullDeploymentsStatus) Value() (driver.Value, error) { return string(ns.DeploymentsStatus), nil } +type EnvironmentVariablesType string + +const ( + EnvironmentVariablesTypeRecoverable EnvironmentVariablesType = "recoverable" + EnvironmentVariablesTypeWriteonly EnvironmentVariablesType = "writeonly" +) + +func (e *EnvironmentVariablesType) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = EnvironmentVariablesType(s) + case string: + *e = EnvironmentVariablesType(s) + default: + return fmt.Errorf("unsupported scan type for EnvironmentVariablesType: %T", src) + } + return nil +} + +type NullEnvironmentVariablesType struct { + EnvironmentVariablesType EnvironmentVariablesType + Valid bool // Valid is true if EnvironmentVariablesType is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullEnvironmentVariablesType) Scan(value interface{}) error { + if value == nil { + ns.EnvironmentVariablesType, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.EnvironmentVariablesType.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullEnvironmentVariablesType) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.EnvironmentVariablesType), nil +} + type GatewaysHealth string const ( @@ -747,6 +789,7 @@ type Deployment struct { RuntimeConfig json.RawMessage `db:"runtime_config"` GatewayConfig []byte `db:"gateway_config"` OpenapiSpec sql.NullString `db:"openapi_spec"` + SecretsConfig []byte `db:"secrets_config"` Status DeploymentsStatus `db:"status"` CreatedAt int64 `db:"created_at"` UpdatedAt sql.NullInt64 `db:"updated_at"` @@ -782,6 +825,19 @@ type Environment struct { UpdatedAt sql.NullInt64 `db:"updated_at"` } +type EnvironmentVariable struct { + ID string `db:"id"` + WorkspaceID string `db:"workspace_id"` + EnvironmentID string `db:"environment_id"` + Key string `db:"key"` + Value string `db:"value"` + Type EnvironmentVariablesType `db:"type"` + Description sql.NullString `db:"description"` + DeleteProtection sql.NullBool `db:"delete_protection"` + CreatedAt int64 `db:"created_at"` + UpdatedAt sql.NullInt64 `db:"updated_at"` +} + type Gateway struct { ID string `db:"id"` WorkspaceID string `db:"workspace_id"` diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index e0fe39c1eb..1e4d63eeb2 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -190,7 +190,7 @@ type Querier interface { FindCustomDomainById(ctx context.Context, db DBTX, id string) (FindCustomDomainByIdRow, error) //FindDeploymentById // - // SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, status, created_at, updated_at FROM `deployments` WHERE id = ? + // SELECT id, workspace_id, project_id, environment_id, git_commit_sha, git_branch, git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, git_commit_timestamp, runtime_config, gateway_config, openapi_spec, secrets_config, status, created_at, updated_at FROM `deployments` WHERE id = ? FindDeploymentById(ctx context.Context, db DBTX, id string) (Deployment, error) //FindDeploymentStepsByDeploymentId // @@ -217,6 +217,13 @@ type Querier interface { // AND project_id = ? // AND slug = ? FindEnvironmentByProjectIdAndSlug(ctx context.Context, db DBTX, arg FindEnvironmentByProjectIdAndSlugParams) (Environment, error) + //FindEnvironmentVariablesByEnvironmentId + // + // SELECT `key`, value + // FROM environment_variables + // WHERE environment_id = ? + // AND deleted_at IS NULL + FindEnvironmentVariablesByEnvironmentId(ctx context.Context, db DBTX, environmentID string) ([]FindEnvironmentVariablesByEnvironmentIdRow, error) //FindGatewaysByEnvironmentID // // SELECT id, workspace_id, environment_id, k8s_service_name, region, image, health, replicas FROM gateways WHERE environment_id = ? @@ -1108,10 +1115,10 @@ type Querier interface { // git_commit_message, // git_commit_author_handle, // git_commit_author_avatar_url, - // git_commit_timestamp, -- Unix epoch milliseconds + // git_commit_timestamp, // openapi_spec, + // secrets_config, // status, - // gateway_config, // created_at, // updated_at // ) diff --git a/go/pkg/db/queries/deployment_insert.sql b/go/pkg/db/queries/deployment_insert.sql index 4473559101..2bf552a811 100644 --- a/go/pkg/db/queries/deployment_insert.sql +++ b/go/pkg/db/queries/deployment_insert.sql @@ -11,10 +11,10 @@ INSERT INTO `deployments` ( git_commit_message, git_commit_author_handle, git_commit_author_avatar_url, - git_commit_timestamp, -- Unix epoch milliseconds + git_commit_timestamp, openapi_spec, + secrets_config, status, - gateway_config, created_at, updated_at ) @@ -32,8 +32,8 @@ VALUES ( sqlc.arg(git_commit_author_avatar_url), sqlc.arg(git_commit_timestamp), sqlc.arg(openapi_spec), + sqlc.arg(secrets_config), sqlc.arg(status), - sqlc.arg(gateway_config), sqlc.arg(created_at), sqlc.arg(updated_at) ); diff --git a/go/pkg/db/queries/environment_variables_find_by_environment_id.sql b/go/pkg/db/queries/environment_variables_find_by_environment_id.sql new file mode 100644 index 0000000000..c2b937ef8d --- /dev/null +++ b/go/pkg/db/queries/environment_variables_find_by_environment_id.sql @@ -0,0 +1,5 @@ +-- name: FindEnvironmentVariablesByEnvironmentId :many +SELECT `key`, value +FROM environment_variables +WHERE environment_id = sqlc.arg(environment_id) + AND deleted_at IS NULL; diff --git a/go/pkg/db/schema.sql b/go/pkg/db/schema.sql index d856d164bd..66eccc8da9 100644 --- a/go/pkg/db/schema.sql +++ b/go/pkg/db/schema.sql @@ -316,6 +316,21 @@ CREATE TABLE `environments` ( CONSTRAINT `environments_project_id_slug_idx` UNIQUE(`project_id`,`slug`) ); +CREATE TABLE `environment_variables` ( + `id` varchar(128) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `environment_id` varchar(128) NOT NULL, + `key` varchar(256) NOT NULL, + `value` varchar(4096) NOT NULL, + `type` enum('recoverable','writeonly') NOT NULL, + `description` varchar(255), + `delete_protection` boolean DEFAULT false, + `created_at` bigint NOT NULL, + `updated_at` bigint, + CONSTRAINT `environment_variables_id` PRIMARY KEY(`id`), + CONSTRAINT `environment_id_key` UNIQUE(`environment_id`,`key`) +); + CREATE TABLE `clickhouse_workspace_settings` ( `workspace_id` varchar(256) NOT NULL, `username` varchar(256) NOT NULL, @@ -363,6 +378,7 @@ CREATE TABLE `deployments` ( `runtime_config` json NOT NULL, `gateway_config` longblob NOT NULL, `openapi_spec` longblob, + `secrets_config` longblob NOT NULL, `status` enum('pending','building','deploying','network','ready','failed') NOT NULL DEFAULT 'pending', `created_at` bigint NOT NULL, `updated_at` bigint, diff --git a/internal/db/src/schema/deployments.ts b/internal/db/src/schema/deployments.ts index 17bdd0cb07..28e3fbc502 100644 --- a/internal/db/src/schema/deployments.ts +++ b/internal/db/src/schema/deployments.ts @@ -46,6 +46,10 @@ export const deployments = mysqlTable( // OpenAPI specification openapiSpec: longblob("openapi_spec"), + // Environment variables snapshot (protobuf: ctrl.v1.SecretsBlob) + // Encrypted values from environment_variables at deploy time + secretsConfig: longblob("secrets_config").notNull(), + // Deployment status status: mysqlEnum("status", ["pending", "building", "deploying", "network", "ready", "failed"]) .notNull() diff --git a/internal/db/src/schema/environment_variables.ts b/internal/db/src/schema/environment_variables.ts index a5f54b777a..cd2c8cbb33 100644 --- a/internal/db/src/schema/environment_variables.ts +++ b/internal/db/src/schema/environment_variables.ts @@ -5,6 +5,7 @@ import { lifecycleDates } from "./util/lifecycle_dates"; import { workspaces } from "./workspaces"; import { environments } from "./environments"; + export const environmentVariables = mysqlTable( "environment_variables", { @@ -15,9 +16,14 @@ export const environmentVariables = mysqlTable( }).notNull(), key: varchar("key", { length: 256 }).notNull(), - // Either the plaintext value or a vault encrypted response - value: varchar("value", { length: 1024 }).notNull(), - type: mysqlEnum("type", ["plaintext", "secret"]).notNull(), + + // Always encrypted via vault (contains keyId, nonce, ciphertext in the blob) + value: varchar("value", { length: 4096 }).notNull(), + + // Both types are encrypted in the database + // - recoverable: can be decrypted and shown in the UI + // - writeonly: cannot be read back after creation + type: mysqlEnum("type", ["recoverable", "writeonly"]).notNull(), description: varchar("description", { length: 255 }), diff --git a/internal/db/src/schema/index.ts b/internal/db/src/schema/index.ts index 8748aa506d..af0bd61103 100644 --- a/internal/db/src/schema/index.ts +++ b/internal/db/src/schema/index.ts @@ -10,6 +10,7 @@ export * from "./identity"; export * from "./quota"; export * from "./audit_logs"; export * from "./environments"; +export * from "./environment_variables"; export * from "./clickhouse_workspace_settings"; // Deployment platform tables From 5b0249ee9d1c163404524565ee7c18934e0a09b2 Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 13:59:47 +0100 Subject: [PATCH 02/18] fix db query --- ...vironment_variables_find_by_environment_id.sql_generated.go | 2 -- go/pkg/db/querier_generated.go | 1 - .../queries/environment_variables_find_by_environment_id.sql | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go b/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go index 45953ba266..590d40c8f4 100644 --- a/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go +++ b/go/pkg/db/environment_variables_find_by_environment_id.sql_generated.go @@ -13,7 +13,6 @@ const findEnvironmentVariablesByEnvironmentId = `-- name: FindEnvironmentVariabl SELECT ` + "`" + `key` + "`" + `, value FROM environment_variables WHERE environment_id = ? - AND deleted_at IS NULL ` type FindEnvironmentVariablesByEnvironmentIdRow struct { @@ -26,7 +25,6 @@ type FindEnvironmentVariablesByEnvironmentIdRow struct { // SELECT `key`, value // FROM environment_variables // WHERE environment_id = ? -// AND deleted_at IS NULL func (q *Queries) FindEnvironmentVariablesByEnvironmentId(ctx context.Context, db DBTX, environmentID string) ([]FindEnvironmentVariablesByEnvironmentIdRow, error) { rows, err := db.QueryContext(ctx, findEnvironmentVariablesByEnvironmentId, environmentID) if err != nil { diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index 1e4d63eeb2..e0cbf969cd 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -222,7 +222,6 @@ type Querier interface { // SELECT `key`, value // FROM environment_variables // WHERE environment_id = ? - // AND deleted_at IS NULL FindEnvironmentVariablesByEnvironmentId(ctx context.Context, db DBTX, environmentID string) ([]FindEnvironmentVariablesByEnvironmentIdRow, error) //FindGatewaysByEnvironmentID // diff --git a/go/pkg/db/queries/environment_variables_find_by_environment_id.sql b/go/pkg/db/queries/environment_variables_find_by_environment_id.sql index c2b937ef8d..866a56b25f 100644 --- a/go/pkg/db/queries/environment_variables_find_by_environment_id.sql +++ b/go/pkg/db/queries/environment_variables_find_by_environment_id.sql @@ -1,5 +1,4 @@ -- name: FindEnvironmentVariablesByEnvironmentId :many SELECT `key`, value FROM environment_variables -WHERE environment_id = sqlc.arg(environment_id) - AND deleted_at IS NULL; +WHERE environment_id = sqlc.arg(environment_id); From 60f228c2edd12aadaf1d46681d7cbf2924816a73 Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 12:03:12 +0100 Subject: [PATCH 03/18] feat: add SecretsConfig proto for encrypted env vars --- .../dashboard/gen/proto/ctrl/v1/secrets_pb.ts | 36 +++++ go/gen/proto/ctrl/v1/secrets.pb.go | 131 ++++++++++++++++++ go/proto/ctrl/v1/secrets.proto | 11 ++ 3 files changed, 178 insertions(+) create mode 100644 apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts create mode 100644 go/gen/proto/ctrl/v1/secrets.pb.go create mode 100644 go/proto/ctrl/v1/secrets.proto diff --git a/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts new file mode 100644 index 0000000000..65f4a72f2f --- /dev/null +++ b/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts @@ -0,0 +1,36 @@ +// @generated by protoc-gen-es v2.8.0 with parameter "target=ts" +// @generated from file ctrl/v1/secrets.proto (package ctrl.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file ctrl/v1/secrets.proto. + */ +export const file_ctrl_v1_secrets: GenFile = /*@__PURE__*/ + fileDesc("ChVjdHJsL3YxL3NlY3JldHMucHJvdG8SB2N0cmwudjEidQoNU2VjcmV0c0NvbmZpZxI0CgdzZWNyZXRzGAEgAygLMiMuY3RybC52MS5TZWNyZXRzQ29uZmlnLlNlY3JldHNFbnRyeRouCgxTZWNyZXRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUKOAQoLY29tLmN0cmwudjFCDFNlY3JldHNQcm90b1ABWjRnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2N0cmwvdjE7Y3RybHYxogIDQ1hYqgIHQ3RybC5WMcoCB0N0cmxcVjHiAhNDdHJsXFYxXEdQQk1ldGFkYXRh6gIIQ3RybDo6VjFiBnByb3RvMw"); + +/** + * SecretsConfig is stored in the deployments table + * Contains encrypted environment variables snapshotted at deploy time + * + * @generated from message ctrl.v1.SecretsConfig + */ +export type SecretsConfig = Message<"ctrl.v1.SecretsConfig"> & { + /** + * key -> encrypted value + * + * @generated from field: map secrets = 1; + */ + secrets: { [key: string]: string }; +}; + +/** + * Describes the message ctrl.v1.SecretsConfig. + * Use `create(SecretsConfigSchema)` to create a new message. + */ +export const SecretsConfigSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_ctrl_v1_secrets, 0); + diff --git a/go/gen/proto/ctrl/v1/secrets.pb.go b/go/gen/proto/ctrl/v1/secrets.pb.go new file mode 100644 index 0000000000..8c947ee05a --- /dev/null +++ b/go/gen/proto/ctrl/v1/secrets.pb.go @@ -0,0 +1,131 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.8 +// protoc (unknown) +// source: ctrl/v1/secrets.proto + +package ctrlv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// SecretsConfig is stored in the deployments table +// Contains encrypted environment variables snapshotted at deploy time +type SecretsConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // key -> encrypted value + Secrets map[string]string `protobuf:"bytes,1,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SecretsConfig) Reset() { + *x = SecretsConfig{} + mi := &file_ctrl_v1_secrets_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SecretsConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretsConfig) ProtoMessage() {} + +func (x *SecretsConfig) ProtoReflect() protoreflect.Message { + mi := &file_ctrl_v1_secrets_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretsConfig.ProtoReflect.Descriptor instead. +func (*SecretsConfig) Descriptor() ([]byte, []int) { + return file_ctrl_v1_secrets_proto_rawDescGZIP(), []int{0} +} + +func (x *SecretsConfig) GetSecrets() map[string]string { + if x != nil { + return x.Secrets + } + return nil +} + +var File_ctrl_v1_secrets_proto protoreflect.FileDescriptor + +const file_ctrl_v1_secrets_proto_rawDesc = "" + + "\n" + + "\x15ctrl/v1/secrets.proto\x12\actrl.v1\"\x8a\x01\n" + + "\rSecretsConfig\x12=\n" + + "\asecrets\x18\x01 \x03(\v2#.ctrl.v1.SecretsConfig.SecretsEntryR\asecrets\x1a:\n" + + "\fSecretsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x8e\x01\n" + + "\vcom.ctrl.v1B\fSecretsProtoP\x01Z4github.com/unkeyed/unkey/go/gen/proto/ctrl/v1;ctrlv1\xa2\x02\x03CXX\xaa\x02\aCtrl.V1\xca\x02\aCtrl\\V1\xe2\x02\x13Ctrl\\V1\\GPBMetadata\xea\x02\bCtrl::V1b\x06proto3" + +var ( + file_ctrl_v1_secrets_proto_rawDescOnce sync.Once + file_ctrl_v1_secrets_proto_rawDescData []byte +) + +func file_ctrl_v1_secrets_proto_rawDescGZIP() []byte { + file_ctrl_v1_secrets_proto_rawDescOnce.Do(func() { + file_ctrl_v1_secrets_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ctrl_v1_secrets_proto_rawDesc), len(file_ctrl_v1_secrets_proto_rawDesc))) + }) + return file_ctrl_v1_secrets_proto_rawDescData +} + +var file_ctrl_v1_secrets_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_ctrl_v1_secrets_proto_goTypes = []any{ + (*SecretsConfig)(nil), // 0: ctrl.v1.SecretsConfig + nil, // 1: ctrl.v1.SecretsConfig.SecretsEntry +} +var file_ctrl_v1_secrets_proto_depIdxs = []int32{ + 1, // 0: ctrl.v1.SecretsConfig.secrets:type_name -> ctrl.v1.SecretsConfig.SecretsEntry + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_ctrl_v1_secrets_proto_init() } +func file_ctrl_v1_secrets_proto_init() { + if File_ctrl_v1_secrets_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_ctrl_v1_secrets_proto_rawDesc), len(file_ctrl_v1_secrets_proto_rawDesc)), + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ctrl_v1_secrets_proto_goTypes, + DependencyIndexes: file_ctrl_v1_secrets_proto_depIdxs, + MessageInfos: file_ctrl_v1_secrets_proto_msgTypes, + }.Build() + File_ctrl_v1_secrets_proto = out.File + file_ctrl_v1_secrets_proto_goTypes = nil + file_ctrl_v1_secrets_proto_depIdxs = nil +} diff --git a/go/proto/ctrl/v1/secrets.proto b/go/proto/ctrl/v1/secrets.proto new file mode 100644 index 0000000000..4a724cd55c --- /dev/null +++ b/go/proto/ctrl/v1/secrets.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package ctrl.v1; + +option go_package = "github.com/unkeyed/unkey/go/gen/proto/ctrl/v1;ctrlv1"; + +// SecretsConfig is stored in the deployments table +// Contains encrypted environment variables snapshotted at deploy time +message SecretsConfig { + // key -> encrypted value + map secrets = 1; +} From ac2921865f2e45445c07829a795ade60ce752273 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:11:51 +0000 Subject: [PATCH 04/18] [autofix.ci] apply automated fixes --- apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts index 65f4a72f2f..493806e854 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/secrets_pb.ts @@ -2,15 +2,18 @@ // @generated from file ctrl/v1/secrets.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ +import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; -import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/secrets.proto. */ -export const file_ctrl_v1_secrets: GenFile = /*@__PURE__*/ - fileDesc("ChVjdHJsL3YxL3NlY3JldHMucHJvdG8SB2N0cmwudjEidQoNU2VjcmV0c0NvbmZpZxI0CgdzZWNyZXRzGAEgAygLMiMuY3RybC52MS5TZWNyZXRzQ29uZmlnLlNlY3JldHNFbnRyeRouCgxTZWNyZXRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUKOAQoLY29tLmN0cmwudjFCDFNlY3JldHNQcm90b1ABWjRnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2N0cmwvdjE7Y3RybHYxogIDQ1hYqgIHQ3RybC5WMcoCB0N0cmxcVjHiAhNDdHJsXFYxXEdQQk1ldGFkYXRh6gIIQ3RybDo6VjFiBnByb3RvMw"); +export const file_ctrl_v1_secrets: GenFile = + /*@__PURE__*/ + fileDesc( + "ChVjdHJsL3YxL3NlY3JldHMucHJvdG8SB2N0cmwudjEidQoNU2VjcmV0c0NvbmZpZxI0CgdzZWNyZXRzGAEgAygLMiMuY3RybC52MS5TZWNyZXRzQ29uZmlnLlNlY3JldHNFbnRyeRouCgxTZWNyZXRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUKOAQoLY29tLmN0cmwudjFCDFNlY3JldHNQcm90b1ABWjRnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2N0cmwvdjE7Y3RybHYxogIDQ1hYqgIHQ3RybC5WMcoCB0N0cmxcVjHiAhNDdHJsXFYxXEdQQk1ldGFkYXRh6gIIQ3RybDo6VjFiBnByb3RvMw", + ); /** * SecretsConfig is stored in the deployments table @@ -31,6 +34,6 @@ export type SecretsConfig = Message<"ctrl.v1.SecretsConfig"> & { * Describes the message ctrl.v1.SecretsConfig. * Use `create(SecretsConfigSchema)` to create a new message. */ -export const SecretsConfigSchema: GenMessage = /*@__PURE__*/ +export const SecretsConfigSchema: GenMessage = + /*@__PURE__*/ messageDesc(file_ctrl_v1_secrets, 0); - From d89e495ae1b7c7b4e99d1804ed05c552a6773450 Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 12:05:02 +0100 Subject: [PATCH 05/18] feat: dashboard UI for environment variables management --- .../env-variables-section/add-env-var-row.tsx | 53 +-- .../bulk-add-env-vars.tsx | 305 ++++++++++++++++++ .../components/env-var-form.tsx | 49 ++- .../components/env-var-inputs.tsx | 29 +- .../env-variables-section/env-var-row.tsx | 162 ++++++---- .../hooks/use-env-var-manager.tsx | 17 +- .../details/env-variables-section/index.tsx | 30 +- .../details/env-variables-section/types.ts | 35 +- .../projects/[projectId]/page.tsx | 28 +- .../gen/proto/cache/v1/invalidation_pb.ts | 13 +- apps/dashboard/gen/proto/ctrl/v1/acme_pb.ts | 22 +- apps/dashboard/gen/proto/ctrl/v1/build_pb.ts | 29 +- .../gen/proto/ctrl/v1/deployment_pb.ts | 108 +++---- .../gen/proto/ctrl/v1/environment_pb.ts | 24 +- .../dashboard/gen/proto/ctrl/v1/openapi_pb.ts | 33 +- .../dashboard/gen/proto/ctrl/v1/project_pb.ts | 21 +- .../dashboard/gen/proto/ctrl/v1/service_pb.ts | 24 +- .../gen/proto/krane/v1/gateway_pb.ts | 55 ++-- .../dashboard/gen/proto/vault/v1/object_pb.ts | 25 +- .../gen/proto/vault/v1/service_pb.ts | 78 ++--- .../trpc/routers/deploy/env-vars/create.ts | 85 +++++ .../trpc/routers/deploy/env-vars/decrypt.ts | 70 ++++ .../trpc/routers/deploy/env-vars/delete.ts | 38 +++ .../lib/trpc/routers/deploy/env-vars/list.ts | 94 ++++++ .../trpc/routers/deploy/env-vars/update.ts | 79 +++++ .../lib/trpc/routers/deploy/envs/list.ts | 80 ----- apps/dashboard/lib/trpc/routers/index.ts | 14 +- apps/docs/docs.json | 45 ++- biome.json | 11 +- internal/id/src/generate.ts | 1 + 30 files changed, 1141 insertions(+), 516 deletions(-) create mode 100644 apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx create mode 100644 apps/dashboard/lib/trpc/routers/deploy/env-vars/create.ts create mode 100644 apps/dashboard/lib/trpc/routers/deploy/env-vars/decrypt.ts create mode 100644 apps/dashboard/lib/trpc/routers/deploy/env-vars/delete.ts create mode 100644 apps/dashboard/lib/trpc/routers/deploy/env-vars/list.ts create mode 100644 apps/dashboard/lib/trpc/routers/deploy/env-vars/update.ts delete mode 100644 apps/dashboard/lib/trpc/routers/deploy/envs/list.ts diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx index 22bfae1432..f737a6640e 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx @@ -1,3 +1,4 @@ +import { trpc } from "@/lib/trpc/client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { EnvVarInputs } from "./components/env-var-inputs"; @@ -6,21 +7,26 @@ import { EnvVarSecretSwitch } from "./components/env-var-secret-switch"; import { type EnvVar, type EnvVarFormData, EnvVarFormSchema } from "./types"; type AddEnvVarRowProps = { - projectId: string; + environmentId: string; getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; onCancel: () => void; + onSuccess: () => void; }; -export function AddEnvVarRow({ getExistingEnvVar, onCancel }: AddEnvVarRowProps) { - // TODO: Add mutation when available - // const upsertMutation = trpc.deploy.project.envs.upsert.useMutation(); +export function AddEnvVarRow({ + environmentId, + getExistingEnvVar, + onCancel, + onSuccess, +}: AddEnvVarRowProps) { + const createMutation = trpc.deploy.envVar.create.useMutation(); const { register, handleSubmit, watch, setValue, - formState: { errors, isValid, isSubmitting }, + formState: { errors, isValid }, } = useForm({ resolver: zodResolver( EnvVarFormSchema.superRefine((data, ctx) => { @@ -37,28 +43,26 @@ export function AddEnvVarRow({ getExistingEnvVar, onCancel }: AddEnvVarRowProps) defaultValues: { key: "", value: "", - type: "env", + type: "recoverable", }, }); const watchedType = watch("type"); + const isSubmitting = createMutation.isLoading; - const handleSave = async (_formData: EnvVarFormData) => { + const handleSave = async (formData: EnvVarFormData) => { try { - // TODO: Call tRPC upsert when available - // await upsertMutation.mutateAsync({ - // projectId, - // ...formData - // }); - - // Mock successful save for now - await new Promise((resolve) => setTimeout(resolve, 500)); - - // Invalidate to refresh data - // TODO - //await trpcUtils.project.envs.getEnvs.invalidate({ projectId }); - - onCancel(); // Close the add form + await createMutation.mutateAsync({ + environmentId, + variables: [ + { + key: formData.key, + value: formData.value, + type: formData.type, + }, + ], + }); + onSuccess(); } catch (error) { console.error("Failed to add env var:", error); } @@ -77,16 +81,17 @@ export function AddEnvVarRow({ getExistingEnvVar, onCancel }: AddEnvVarRowProps)
- setValue("type", checked ? "secret" : "env", { + setValue("type", checked ? "writeonly" : "recoverable", { shouldDirty: true, shouldValidate: true, }) diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx new file mode 100644 index 0000000000..90de2126d3 --- /dev/null +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx @@ -0,0 +1,305 @@ +import { trpc } from "@/lib/trpc/client"; +import { cn } from "@/lib/utils"; +import { Plus, Trash } from "@unkey/icons"; +import { Button } from "@unkey/ui"; +import { useEffect, useRef, useState } from "react"; +import { EnvVarSecretSwitch } from "./components/env-var-secret-switch"; +import type { EnvVar, EnvVarType } from "./types"; + +type EnvVarEntry = { + id: string; + key: string; + value: string; + type: EnvVarType; +}; + +type BulkAddEnvVarsProps = { + environmentId: string; + getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; + onCancel: () => void; + onSuccess: () => void; +}; + +function cleanEnvValue(raw: string): string { + let value = raw.trim(); + + // Check if value is quoted + const isDoubleQuoted = value.startsWith('"'); + const isSingleQuoted = value.startsWith("'"); + + if (isDoubleQuoted || isSingleQuoted) { + const quote = isDoubleQuoted ? '"' : "'"; + const endQuoteIndex = value.indexOf(quote, 1); + if (endQuoteIndex !== -1) { + // Extract content between quotes + value = value.slice(1, endQuoteIndex); + } else { + // No closing quote, just remove the opening one + value = value.slice(1); + } + } else { + // Unquoted value - remove trailing comments + const commentIndex = value.indexOf(" #"); + if (commentIndex !== -1) { + value = value.slice(0, commentIndex); + } + // Also check for # without space (less common but valid) + const hashIndex = value.indexOf("#"); + if (hashIndex !== -1 && !value.slice(0, hashIndex).includes(" ")) { + // Only trim if # appears to be a comment, not part of the value + // This is a heuristic - if there's no space before #, it might be part of value + } + } + + return value.trim(); +} + +function parseEnvFile(content: string): EnvVarEntry[] { + const lines = content.split("\n"); + const entries: EnvVarEntry[] = []; + + for (const line of lines) { + const trimmed = line.trim(); + // Skip empty lines and comments + if (!trimmed || trimmed.startsWith("#")) { + continue; + } + + const eqIndex = trimmed.indexOf("="); + if (eqIndex === -1) { + continue; + } + + const key = trimmed.slice(0, eqIndex).trim(); + const value = cleanEnvValue(trimmed.slice(eqIndex + 1)); + + const upperKey = key.toUpperCase(); + if (upperKey && /^[A-Z][A-Z0-9_]*$/.test(upperKey)) { + entries.push({ + id: crypto.randomUUID(), + key: upperKey, + value, + type: "recoverable", + }); + } + } + + return entries; +} + +export function BulkAddEnvVars({ + environmentId, + getExistingEnvVar, + onCancel, + onSuccess, +}: BulkAddEnvVarsProps) { + const createMutation = trpc.deploy.envVar.create.useMutation(); + const containerRef = useRef(null); + const [entries, setEntries] = useState([ + { id: crypto.randomUUID(), key: "", value: "", type: "recoverable" }, + ]); + + // Scroll into view when component mounts + useEffect(() => { + containerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }); + }, []); + + const isSubmitting = createMutation.isLoading; + + const addEntry = () => { + const newEntry = { id: crypto.randomUUID(), key: "", value: "", type: "recoverable" as const }; + setEntries([...entries, newEntry]); + // Focus the new entry's key input after render + setTimeout(() => { + const inputs = containerRef.current?.querySelectorAll( + 'input[placeholder="KEY"]', + ); + inputs?.[inputs.length - 1]?.focus(); + }, 0); + }; + + const handleKeyDown = (e: React.KeyboardEvent, entryId: string, field: "key" | "value") => { + if (e.key === "Enter") { + e.preventDefault(); + const entryIndex = entries.findIndex((entry) => entry.id === entryId); + const isLastEntry = entryIndex === entries.length - 1; + + if (field === "value" && isLastEntry) { + // On last entry's value field, create a new row + addEntry(); + } else if (field === "key") { + // Move focus to value field + const valueInput = (e.target as HTMLInputElement) + .closest(".flex") + ?.querySelector('input[placeholder="value"]'); + valueInput?.focus(); + } else if (field === "value" && !isLastEntry) { + // Move focus to next row's key field + const allRows = containerRef.current?.querySelectorAll( + ".flex.items-center.gap-2", + ); + const nextRow = allRows?.[entryIndex + 1]; + nextRow?.querySelector('input[placeholder="KEY"]')?.focus(); + } + } else if (e.key === "Escape") { + onCancel(); + } + }; + + const removeEntry = (id: string) => { + if (entries.length > 1) { + setEntries(entries.filter((e) => e.id !== id)); + } + }; + + const updateEntry = (id: string, field: keyof EnvVarEntry, value: string | EnvVarType) => { + // Auto-uppercase the key field and replace spaces with underscores + const transformedValue = + field === "key" && typeof value === "string" ? value.toUpperCase().replace(/ /g, "_") : value; + setEntries(entries.map((e) => (e.id === id ? { ...e, [field]: transformedValue } : e))); + }; + + const handlePaste = (e: React.ClipboardEvent, entryId: string) => { + const pastedText = e.clipboardData.getData("text"); + + // Check if it looks like an .env file (multiple lines with = signs) + if (pastedText.includes("\n") && pastedText.includes("=")) { + e.preventDefault(); + const parsed = parseEnvFile(pastedText); + if (parsed.length > 0) { + // Replace the current entry and add new ones + const currentIndex = entries.findIndex((e) => e.id === entryId); + const newEntries = [...entries]; + newEntries.splice(currentIndex, 1, ...parsed); + setEntries(newEntries); + } + } + }; + + const getErrors = (entry: EnvVarEntry): { key?: string; value?: string } => { + const errors: { key?: string; value?: string } = {}; + + if (entry.key && !/^[A-Z][A-Z0-9_]*$/.test(entry.key)) { + errors.key = "Must be UPPERCASE"; + } else if (entry.key && getExistingEnvVar(entry.key)) { + errors.key = "Already exists"; + } else if (entry.key) { + // Check for duplicates within the current entries + const duplicates = entries.filter((e) => e.key === entry.key); + if (duplicates.length > 1) { + errors.key = "Duplicate"; + } + } + + return errors; + }; + + const validEntries = entries.filter((e) => { + const errors = getErrors(e); + return e.key && e.value && !errors.key && !errors.value; + }); + + const handleSave = async () => { + if (validEntries.length === 0) { + return; + } + + try { + await createMutation.mutateAsync({ + environmentId, + variables: validEntries.map((e) => ({ + key: e.key, + value: e.value, + type: e.type, + })), + }); + onSuccess(); + } catch (error) { + console.error("Failed to add env vars:", error); + } + }; + + return ( +
+
+ + Add variables (paste .env file content to bulk import) + +
+ +
+ {entries.map((entry) => { + const errors = getErrors(entry); + return ( +
+ updateEntry(entry.id, "key", e.target.value)} + onKeyDown={(e) => handleKeyDown(e, entry.id, "key")} + onPaste={(e) => handlePaste(e, entry.id)} + className={cn( + "w-32 px-2 py-1 text-xs font-mono bg-gray-3 border rounded focus:outline-none focus:ring-1", + errors.key + ? "border-error-9 focus:ring-error-9" + : "border-gray-6 focus:ring-accent-9", + )} + /> + = + updateEntry(entry.id, "value", e.target.value)} + onKeyDown={(e) => handleKeyDown(e, entry.id, "value")} + onPaste={(e) => handlePaste(e, entry.id)} + className="flex-1 px-2 py-1 text-xs font-mono bg-gray-3 border border-gray-6 rounded focus:outline-none focus:ring-1 focus:ring-accent-9" + /> + + updateEntry(entry.id, "type", checked ? "writeonly" : "recoverable") + } + disabled={isSubmitting} + /> + +
+ ); + })} +
+ +
+ +
+ + +
+
+
+ ); +} diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-form.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-form.tsx index a3f44a455f..0e1f2d2aa2 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-form.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-form.tsx @@ -1,3 +1,4 @@ +import { trpc } from "@/lib/trpc/client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { type EnvVar, type EnvVarFormData, EnvVarFormSchema } from "../types"; @@ -6,6 +7,7 @@ import { EnvVarSaveActions } from "./env-var-save-actions"; import { EnvVarSecretSwitch } from "./env-var-secret-switch"; type EnvVarFormProps = { + envVarId: string; initialData: EnvVarFormData; projectId: string; getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; @@ -13,31 +15,32 @@ type EnvVarFormProps = { onCancel: () => void; excludeId?: string; autoFocus?: boolean; - decrypted?: boolean; className?: string; }; export function EnvVarForm({ + envVarId, initialData, projectId, getExistingEnvVar, onSuccess, onCancel, excludeId, - decrypted, autoFocus = false, className = "w-full flex px-4 py-3 bg-gray-2 border-b border-gray-4 last:border-b-0", }: EnvVarFormProps) { console.debug(projectId); - // TODO: Add mutations when available - // const upsertMutation = trpc.deploy.project.envs.upsert.useMutation(); + const updateMutation = trpc.deploy.envVar.update.useMutation(); + + // Writeonly vars cannot have their key renamed + const isWriteOnly = initialData.type === "writeonly"; const { register, handleSubmit, watch, setValue, - formState: { errors, isValid, isSubmitting }, + formState: { errors, isValid }, } = useForm({ resolver: zodResolver( EnvVarFormSchema.superRefine((data, ctx) => { @@ -56,28 +59,23 @@ export function EnvVarForm({ const watchedType = watch("type"); - const handleSave = async (_formData: EnvVarFormData) => { + const handleSave = async (formData: EnvVarFormData) => { try { - // TODO: Call tRPC upsert when available - // await upsertMutation.mutateAsync({ - // projectId, - // id: excludeId, // Will be undefined for new entries - // ...formData - // }); - - // Mock successful save for now - await new Promise((resolve) => setTimeout(resolve, 500)); - - // Invalidate to refresh data - // await trpcUtils.deploy.project.envs.getEnvs.invalidate({ projectId }); - + await updateMutation.mutateAsync({ + envVarId, + key: isWriteOnly ? undefined : formData.key, + value: formData.value, + type: formData.type, + }); onSuccess(); } catch (error) { console.error("Failed to save env var:", error); - throw error; // Re-throw to let form handle the error state + throw error; } }; + const isSubmitting = updateMutation.isLoading; + const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && isValid && !isSubmitting) { handleSubmit(handleSave)(); @@ -91,22 +89,23 @@ export function EnvVarForm({
- setValue("type", checked ? "secret" : "env", { + setValue("type", checked ? "writeonly" : "recoverable", { shouldDirty: true, shouldValidate: true, }) } - disabled={isSubmitting} + disabled={isSubmitting || Boolean(envVarId)} /> ; + setValue: UseFormSetValue; errors: FieldErrors; isSecret: boolean; + keyDisabled?: boolean; onKeyDown?: (e: React.KeyboardEvent) => void; - decrypted?: boolean; autoFocus?: boolean; }; export const EnvVarInputs = forwardRef( - ({ register, errors, isSecret, onKeyDown, autoFocus = false, decrypted }, ref) => { + ({ register, setValue, errors, isSecret, keyDisabled, onKeyDown, autoFocus = false }, ref) => { + const keyRegister = register("key"); + return (
{ + if (keyDisabled) { + return; + } + // Auto-uppercase the key and replace spaces with underscores + setValue("key", e.target.value.toUpperCase().replace(/ /g, "_"), { + shouldValidate: true, + }); + }} onKeyDown={onKeyDown} - placeholder="Variable name" + placeholder="KEY_NAME" + disabled={keyDisabled} className={cn( - "min-h-[32px] text-xs w-[108px] font-mono", + "min-h-[32px] text-xs w-[108px] font-mono uppercase", errors.key && "border-red-6 focus:border-red-7", + keyDisabled && "opacity-50 cursor-not-allowed", )} autoFocus={autoFocus} autoComplete="off" spellCheck={false} - autoCapitalize="none" aria-invalid={Boolean(errors.key)} />
@@ -42,7 +55,7 @@ export const EnvVarInputs = forwardRef( "min-h-[32px] text-xs flex-1 font-mono", errors.value && "border-red-6 focus:border-red-7", )} - type={isSecret && !decrypted ? "password" : "text"} + type={isSecret ? "password" : "text"} autoComplete={isSecret ? "new-password" : "off"} spellCheck={false} autoCapitalize="none" diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/env-var-row.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/env-var-row.tsx index 6f00be3f8c..1d4876ed3e 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/env-var-row.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/env-var-row.tsx @@ -1,3 +1,4 @@ +import { trpc } from "@/lib/trpc/client"; import { cn } from "@/lib/utils"; import { Eye, EyeSlash, PenWriting3, Trash } from "@unkey/icons"; import { Button } from "@unkey/ui"; @@ -9,121 +10,151 @@ type EnvVarRowProps = { envVar: EnvVar; projectId: string; getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; + onDelete?: () => void; + onUpdate?: () => void; }; -export function EnvVarRow({ envVar, projectId, getExistingEnvVar }: EnvVarRowProps) { +export function EnvVarRow({ + envVar, + projectId, + getExistingEnvVar, + onDelete, + onUpdate, +}: EnvVarRowProps) { const [isEditing, setIsEditing] = useState(false); - const [isDecrypted, setIsDecrypted] = useState(false); - // INFO: Won't be necessary once we add tRPC then we can use isSubmitting - const [isSecretLoading, setIsSecretLoading] = useState(false); + const [isRevealed, setIsRevealed] = useState(false); const [decryptedValue, setDecryptedValue] = useState(); + const [isLoadingForEdit, setIsLoadingForEdit] = useState(false); - // TODO: Add mutations when available - // const deleteMutation = trpc.deploy.project.envs.delete.useMutation(); - // const decryptMutation = trpc.deploy.project.envs.decrypt.useMutation(); + const decryptMutation = trpc.deploy.envVar.decrypt.useMutation(); + const deleteMutation = trpc.deploy.envVar.delete.useMutation(); const handleDelete = async () => { try { - // TODO: Call tRPC delete when available - // await deleteMutation.mutateAsync({ - // projectId, - // id: envVar.id - // }); + await deleteMutation.mutateAsync({ envVarId: envVar.id }); + onDelete?.(); + } catch (error) { + console.error("Failed to delete:", error); + } + }; - // Mock successful delete for now - await new Promise((resolve) => setTimeout(resolve, 300)); + const isDeleting = deleteMutation.isLoading; - // Invalidate to refresh data - // TODO await trpcUtils.deploy.project.envs.getEnvs.invalidate({ projectId }); - } catch (error) { - console.error("Failed to delete env var:", error); + // Only recoverable vars can be revealed/decrypted + const isRecoverable = envVar.type === "recoverable"; + + const handleEdit = async () => { + // For recoverable vars, decrypt first if not already decrypted + if (isRecoverable && !decryptedValue) { + setIsLoadingForEdit(true); + try { + const result = await decryptMutation.mutateAsync({ + envVarId: envVar.id, + }); + setDecryptedValue(result.value); + setIsRevealed(true); + } catch (error) { + console.error("Failed to decrypt:", error); + setIsLoadingForEdit(false); + return; + } + setIsLoadingForEdit(false); } + setIsEditing(true); }; - const handleToggleSecret = async () => { - if (envVar.type !== "secret") { + const handleToggleReveal = async () => { + if (!isRecoverable) { return; } - // This stupid nested branching won't be necessary once we have the actual tRPC. So disregard this when reviewing - if (isDecrypted) { - setIsDecrypted(false); + if (isRevealed) { + setIsRevealed(false); } else { if (decryptedValue) { - setIsDecrypted(true); + setIsRevealed(true); } else { - setIsSecretLoading(true); try { - // TODO: Call tRPC decrypt when available - // const result = await decryptMutation.mutateAsync({ - // projectId, - // envVarId: envVar.id - // }); - - // Mock decrypted value for now - await new Promise((resolve) => setTimeout(resolve, 800)); - const mockDecrypted = `decrypted-${envVar.key}`; - - setDecryptedValue(mockDecrypted); - setIsDecrypted(true); + const result = await decryptMutation.mutateAsync({ + envVarId: envVar.id, + }); + setDecryptedValue(result.value); + setIsRevealed(true); } catch (error) { - console.error("Failed to decrypt secret:", error); - } finally { - setIsSecretLoading(false); + console.error("Failed to decrypt:", error); } } } }; + const isLoading = decryptMutation.isLoading && !isLoadingForEdit; + if (isEditing) { return ( setIsEditing(false)} - onCancel={() => setIsEditing(false)} + onSuccess={() => { + setIsEditing(false); + setIsRevealed(false); + onUpdate?.(); + }} + onCancel={() => { + setIsEditing(false); + setIsRevealed(false); + }} className="w-full flex px-4 py-3 bg-gray-2 h-12" /> ); } + // Determine what value to display + const displayValue = (() => { + if (isLoading) { + return "Loading..."; + } + if (isRevealed && decryptedValue) { + return decryptedValue; + } + return "••••••••••••••••"; + })(); + return (
-
{envVar.key}
+
+ {envVar.key} +
=
- {envVar.type === "secret" && !isDecrypted - ? "••••••••••••••••" - : envVar.type === "secret" && isSecretLoading - ? "Loading..." - : envVar.type === "secret" && isDecrypted && decryptedValue - ? decryptedValue - : envVar.value} + {displayValue}
- {envVar.type === "secret" && ( + {isRecoverable && ( -
diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/hooks/use-env-var-manager.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/hooks/use-env-var-manager.tsx index 145bb83545..57ca3fb967 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/hooks/use-env-var-manager.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/hooks/use-env-var-manager.tsx @@ -1,5 +1,5 @@ import { trpc } from "@/lib/trpc/client"; -import type { Environment } from "../types"; +import type { EnvVar, Environment } from "../types"; type UseEnvVarsManagerProps = { projectId: string; @@ -7,9 +7,12 @@ type UseEnvVarsManagerProps = { }; export function useEnvVarsManager({ projectId, environment }: UseEnvVarsManagerProps) { - const { data } = trpc.deploy.environment.list_dummy.useQuery({ projectId }); + const { data, isLoading, error } = trpc.deploy.envVar.list.useQuery({ projectId }); + const utils = trpc.useUtils(); - const envVars = data?.[environment] ?? []; + const environmentData = data?.[environment]; + const environmentId = environmentData?.id; + const envVars: EnvVar[] = environmentData?.variables ?? []; // Helper to check for duplicate environment variable keys within the current environment. // Used for client-side validation before making server requests. @@ -17,8 +20,16 @@ export function useEnvVarsManager({ projectId, environment }: UseEnvVarsManagerP return envVars.find((envVar) => envVar.key.trim() === key.trim() && envVar.id !== excludeId); }; + const invalidate = () => { + utils.deploy.envVar.list.invalidate({ projectId }); + }; + return { + environmentId, envVars, getExistingEnvVar, + isLoading, + error, + invalidate, }; } diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/index.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/index.tsx index d24b314d64..7b425c3b27 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/index.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/index.tsx @@ -2,7 +2,7 @@ import { cn } from "@/lib/utils"; import { ChevronDown, Plus } from "@unkey/icons"; import { Button } from "@unkey/ui"; import { type ReactNode, useState } from "react"; -import { AddEnvVarRow } from "./add-env-var-row"; +import { BulkAddEnvVars } from "./bulk-add-env-vars"; import { EnvVarRow } from "./env-var-row"; import { useEnvVarsManager } from "./hooks/use-env-var-manager"; import type { Environment } from "./types"; @@ -30,7 +30,7 @@ export function EnvironmentVariablesSection({ environment, title, }: EnvironmentVariablesSectionProps) { - const { envVars, getExistingEnvVar } = useEnvVarsManager({ + const { environmentId, envVars, getExistingEnvVar, invalidate } = useEnvVarsManager({ projectId, environment, }); @@ -90,8 +90,10 @@ export function EnvironmentVariablesSection({ {/* Expandable Content */}
))} - {isAddingNew && ( -
- -
+ {isAddingNew && environmentId && ( + { + invalidate(); + cancelAdding(); + }} + /> )} {envVars.length === 0 && !isAddingNew && } diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/types.ts b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/types.ts index c8ea587f67..c372c12531 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/types.ts +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/types.ts @@ -1,25 +1,18 @@ import { z } from "zod"; -export const EnvVarTypeSchema = z.enum(["env", "secret"]); +// Both types are encrypted in the database +// - recoverable: can be decrypted and shown in the UI +// - writeonly: cannot be read back after creation +export const EnvVarTypeSchema = z.enum(["recoverable", "writeonly"]); export type EnvVarType = z.infer; -export const envVarSchema = z - .object({ - id: z.string(), - key: z.string(), - value: z.string(), // For 'env': actual value, for 'secret': encrypted blob - type: EnvVarTypeSchema, - decryptedValue: z.string().optional(), // Only populated when user views secret - }) - .superRefine((data, ctx) => { - if (data.type !== "secret" && data.decryptedValue) { - ctx.addIssue({ - code: "custom", - path: ["decryptedValue"], - message: "Only allowed for secrets", - }); - } - }); +export const envVarSchema = z.object({ + id: z.string(), + key: z.string(), + value: z.string(), // For 'recoverable': decrypted value, for 'writeonly': masked (e.g. "••••••••") + type: EnvVarTypeSchema, + description: z.string().nullable().optional(), +}); export type EnvVar = z.infer; @@ -28,11 +21,11 @@ export const EnvVarFormSchema = z.object({ .string() .trim() .min(1, "Variable name is required") - .regex(/^[A-Za-z][A-Za-z0-9_]*$/, "Use letters, numbers, and underscores; start with a letter"), + .regex(/^[A-Z][A-Z0-9_]*$/, "Must be UPPERCASE with letters, numbers, and underscores only"), value: z.string().min(1, "Variable value is required"), type: EnvVarTypeSchema, }); export type EnvVarFormData = z.infer; -export const EnvironmentSchema = z.enum(["production", "preview"]); -export type Environment = z.infer; +// Environment slug type - this should match the slugs stored in the database +export type Environment = string; diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/page.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/page.tsx index 63d6571d58..b6dc5784c8 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/page.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/page.tsx @@ -25,6 +25,8 @@ export default function ProjectDetails() { [project?.liveDeploymentId], ); + const { data: environments } = useLiveQuery((q) => q.from({ env: collections.environments })); + return (
@@ -58,18 +60,20 @@ export default function ProjectDetails() { title="Environment Variables" />
- } - title="Production" - projectId={projectId} - environment="production" - /> - } - title="Preview" - projectId={projectId} - environment="preview" - /> + {environments?.map((env) => ( + } + title={env.slug} + projectId={projectId} + environment={env.slug} + /> + ))} + {environments?.length === 0 && ( +
+ No environments configured +
+ )}
diff --git a/apps/dashboard/gen/proto/cache/v1/invalidation_pb.ts b/apps/dashboard/gen/proto/cache/v1/invalidation_pb.ts index 90f1a77f60..ea7f19c7e3 100644 --- a/apps/dashboard/gen/proto/cache/v1/invalidation_pb.ts +++ b/apps/dashboard/gen/proto/cache/v1/invalidation_pb.ts @@ -2,18 +2,15 @@ // @generated from file cache/v1/invalidation.proto (package cache.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file cache/v1/invalidation.proto. */ -export const file_cache_v1_invalidation: GenFile = - /*@__PURE__*/ - fileDesc( - "ChtjYWNoZS92MS9pbnZhbGlkYXRpb24ucHJvdG8SCGNhY2hlLnYxImsKFkNhY2hlSW52YWxpZGF0aW9uRXZlbnQSEgoKY2FjaGVfbmFtZRgBIAEoCRIRCgljYWNoZV9rZXkYAiABKAkSEQoJdGltZXN0YW1wGAMgASgDEhcKD3NvdXJjZV9pbnN0YW5jZRgEIAEoCUKaAQoMY29tLmNhY2hlLnYxQhFJbnZhbGlkYXRpb25Qcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2NhY2hlL3YxO2NhY2hldjGiAgNDWFiqAghDYWNoZS5WMcoCCENhY2hlXFYx4gIUQ2FjaGVcVjFcR1BCTWV0YWRhdGHqAglDYWNoZTo6VjFiBnByb3RvMw", - ); +export const file_cache_v1_invalidation: GenFile = /*@__PURE__*/ + fileDesc("ChtjYWNoZS92MS9pbnZhbGlkYXRpb24ucHJvdG8SCGNhY2hlLnYxImsKFkNhY2hlSW52YWxpZGF0aW9uRXZlbnQSEgoKY2FjaGVfbmFtZRgBIAEoCRIRCgljYWNoZV9rZXkYAiABKAkSEQoJdGltZXN0YW1wGAMgASgDEhcKD3NvdXJjZV9pbnN0YW5jZRgEIAEoCUKaAQoMY29tLmNhY2hlLnYxQhFJbnZhbGlkYXRpb25Qcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2NhY2hlL3YxO2NhY2hldjGiAgNDWFiqAghDYWNoZS5WMcoCCENhY2hlXFYx4gIUQ2FjaGVcVjFcR1BCTWV0YWRhdGHqAglDYWNoZTo6VjFiBnByb3RvMw"); /** * CacheInvalidationEvent represents a cache invalidation event @@ -54,6 +51,6 @@ export type CacheInvalidationEvent = Message<"cache.v1.CacheInvalidationEvent"> * Describes the message cache.v1.CacheInvalidationEvent. * Use `create(CacheInvalidationEventSchema)` to create a new message. */ -export const CacheInvalidationEventSchema: GenMessage = - /*@__PURE__*/ +export const CacheInvalidationEventSchema: GenMessage = /*@__PURE__*/ messageDesc(file_cache_v1_invalidation, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/acme_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/acme_pb.ts index 75c479df26..aa8284a482 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/acme_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/acme_pb.ts @@ -2,20 +2,16 @@ // @generated from file ctrl/v1/acme.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/acme.proto. */ -export const file_ctrl_v1_acme: GenFile = - /*@__PURE__*/ - fileDesc( - "ChJjdHJsL3YxL2FjbWUucHJvdG8SB2N0cmwudjEiOQoYVmVyaWZ5Q2VydGlmaWNhdGVSZXF1ZXN0Eg4KBmRvbWFpbhgBIAEoCRINCgV0b2tlbhgCIAEoCSIyChlWZXJpZnlDZXJ0aWZpY2F0ZVJlc3BvbnNlEhUKDWF1dGhvcml6YXRpb24YASABKAkyawoLQWNtZVNlcnZpY2USXAoRVmVyaWZ5Q2VydGlmaWNhdGUSIS5jdHJsLnYxLlZlcmlmeUNlcnRpZmljYXRlUmVxdWVzdBoiLmN0cmwudjEuVmVyaWZ5Q2VydGlmaWNhdGVSZXNwb25zZSIAQosBCgtjb20uY3RybC52MUIJQWNtZVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - [file_google_protobuf_timestamp], - ); +export const file_ctrl_v1_acme: GenFile = /*@__PURE__*/ + fileDesc("ChJjdHJsL3YxL2FjbWUucHJvdG8SB2N0cmwudjEiOQoYVmVyaWZ5Q2VydGlmaWNhdGVSZXF1ZXN0Eg4KBmRvbWFpbhgBIAEoCRINCgV0b2tlbhgCIAEoCSIyChlWZXJpZnlDZXJ0aWZpY2F0ZVJlc3BvbnNlEhUKDWF1dGhvcml6YXRpb24YASABKAkyawoLQWNtZVNlcnZpY2USXAoRVmVyaWZ5Q2VydGlmaWNhdGUSIS5jdHJsLnYxLlZlcmlmeUNlcnRpZmljYXRlUmVxdWVzdBoiLmN0cmwudjEuVmVyaWZ5Q2VydGlmaWNhdGVSZXNwb25zZSIAQosBCgtjb20uY3RybC52MUIJQWNtZVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", [file_google_protobuf_timestamp]); /** * @generated from message ctrl.v1.VerifyCertificateRequest @@ -36,8 +32,7 @@ export type VerifyCertificateRequest = Message<"ctrl.v1.VerifyCertificateRequest * Describes the message ctrl.v1.VerifyCertificateRequest. * Use `create(VerifyCertificateRequestSchema)` to create a new message. */ -export const VerifyCertificateRequestSchema: GenMessage = - /*@__PURE__*/ +export const VerifyCertificateRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_acme, 0); /** @@ -54,8 +49,7 @@ export type VerifyCertificateResponse = Message<"ctrl.v1.VerifyCertificateRespon * Describes the message ctrl.v1.VerifyCertificateResponse. * Use `create(VerifyCertificateResponseSchema)` to create a new message. */ -export const VerifyCertificateResponseSchema: GenMessage = - /*@__PURE__*/ +export const VerifyCertificateResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_acme, 1); /** @@ -69,5 +63,7 @@ export const AcmeService: GenService<{ methodKind: "unary"; input: typeof VerifyCertificateRequestSchema; output: typeof VerifyCertificateResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_acme, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_acme, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/build_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/build_pb.ts index 80a4508d28..76596d3641 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/build_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/build_pb.ts @@ -2,18 +2,15 @@ // @generated from file ctrl/v1/build.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/build.proto. */ -export const file_ctrl_v1_build: GenFile = - /*@__PURE__*/ - fileDesc( - "ChNjdHJsL3YxL2J1aWxkLnByb3RvEgdjdHJsLnYxIqkBChJDcmVhdGVCdWlsZFJlcXVlc3QSGgoSYnVpbGRfY29udGV4dF9wYXRoGAEgASgJEhwKD2RvY2tlcmZpbGVfcGF0aBgCIAEoCUgAiAEBEhgKEHVua2V5X3Byb2plY3RfaWQYAyABKAkSFQoNZGVwbG95bWVudF9pZBgEIAEoCRIUCgx3b3Jrc3BhY2VfaWQYBSABKAlCEgoQX2RvY2tlcmZpbGVfcGF0aCJVChNDcmVhdGVCdWlsZFJlc3BvbnNlEhIKCmltYWdlX25hbWUYASABKAkSEAoIYnVpbGRfaWQYAiABKAkSGAoQZGVwb3RfcHJvamVjdF9pZBgDIAEoCSI0ChhHZW5lcmF0ZVVwbG9hZFVSTFJlcXVlc3QSGAoQdW5rZXlfcHJvamVjdF9pZBgBIAEoCSJfChlHZW5lcmF0ZVVwbG9hZFVSTFJlc3BvbnNlEhIKCnVwbG9hZF91cmwYASABKAkSGgoSYnVpbGRfY29udGV4dF9wYXRoGAIgASgJEhIKCmV4cGlyZXNfaW4YAyABKAMyuAEKDEJ1aWxkU2VydmljZRJKCgtDcmVhdGVCdWlsZBIbLmN0cmwudjEuQ3JlYXRlQnVpbGRSZXF1ZXN0GhwuY3RybC52MS5DcmVhdGVCdWlsZFJlc3BvbnNlIgASXAoRR2VuZXJhdGVVcGxvYWRVUkwSIS5jdHJsLnYxLkdlbmVyYXRlVXBsb2FkVVJMUmVxdWVzdBoiLmN0cmwudjEuR2VuZXJhdGVVcGxvYWRVUkxSZXNwb25zZSIAQowBCgtjb20uY3RybC52MUIKQnVpbGRQcm90b1ABWjRnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2N0cmwvdjE7Y3RybHYxogIDQ1hYqgIHQ3RybC5WMcoCB0N0cmxcVjHiAhNDdHJsXFYxXEdQQk1ldGFkYXRh6gIIQ3RybDo6VjFiBnByb3RvMw", - ); +export const file_ctrl_v1_build: GenFile = /*@__PURE__*/ + fileDesc("ChNjdHJsL3YxL2J1aWxkLnByb3RvEgdjdHJsLnYxIqkBChJDcmVhdGVCdWlsZFJlcXVlc3QSGgoSYnVpbGRfY29udGV4dF9wYXRoGAEgASgJEhwKD2RvY2tlcmZpbGVfcGF0aBgCIAEoCUgAiAEBEhgKEHVua2V5X3Byb2plY3RfaWQYAyABKAkSFQoNZGVwbG95bWVudF9pZBgEIAEoCRIUCgx3b3Jrc3BhY2VfaWQYBSABKAlCEgoQX2RvY2tlcmZpbGVfcGF0aCJVChNDcmVhdGVCdWlsZFJlc3BvbnNlEhIKCmltYWdlX25hbWUYASABKAkSEAoIYnVpbGRfaWQYAiABKAkSGAoQZGVwb3RfcHJvamVjdF9pZBgDIAEoCSI0ChhHZW5lcmF0ZVVwbG9hZFVSTFJlcXVlc3QSGAoQdW5rZXlfcHJvamVjdF9pZBgBIAEoCSJfChlHZW5lcmF0ZVVwbG9hZFVSTFJlc3BvbnNlEhIKCnVwbG9hZF91cmwYASABKAkSGgoSYnVpbGRfY29udGV4dF9wYXRoGAIgASgJEhIKCmV4cGlyZXNfaW4YAyABKAMyuAEKDEJ1aWxkU2VydmljZRJKCgtDcmVhdGVCdWlsZBIbLmN0cmwudjEuQ3JlYXRlQnVpbGRSZXF1ZXN0GhwuY3RybC52MS5DcmVhdGVCdWlsZFJlc3BvbnNlIgASXAoRR2VuZXJhdGVVcGxvYWRVUkwSIS5jdHJsLnYxLkdlbmVyYXRlVXBsb2FkVVJMUmVxdWVzdBoiLmN0cmwudjEuR2VuZXJhdGVVcGxvYWRVUkxSZXNwb25zZSIAQowBCgtjb20uY3RybC52MUIKQnVpbGRQcm90b1ABWjRnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2N0cmwvdjE7Y3RybHYxogIDQ1hYqgIHQ3RybC5WMcoCB0N0cmxcVjHiAhNDdHJsXFYxXEdQQk1ldGFkYXRh6gIIQ3RybDo6VjFiBnByb3RvMw"); /** * @generated from message ctrl.v1.CreateBuildRequest @@ -55,8 +52,7 @@ export type CreateBuildRequest = Message<"ctrl.v1.CreateBuildRequest"> & { * Describes the message ctrl.v1.CreateBuildRequest. * Use `create(CreateBuildRequestSchema)` to create a new message. */ -export const CreateBuildRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateBuildRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_build, 0); /** @@ -89,8 +85,7 @@ export type CreateBuildResponse = Message<"ctrl.v1.CreateBuildResponse"> & { * Describes the message ctrl.v1.CreateBuildResponse. * Use `create(CreateBuildResponseSchema)` to create a new message. */ -export const CreateBuildResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateBuildResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_build, 1); /** @@ -109,8 +104,7 @@ export type GenerateUploadURLRequest = Message<"ctrl.v1.GenerateUploadURLRequest * Describes the message ctrl.v1.GenerateUploadURLRequest. * Use `create(GenerateUploadURLRequestSchema)` to create a new message. */ -export const GenerateUploadURLRequestSchema: GenMessage = - /*@__PURE__*/ +export const GenerateUploadURLRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_build, 2); /** @@ -143,8 +137,7 @@ export type GenerateUploadURLResponse = Message<"ctrl.v1.GenerateUploadURLRespon * Describes the message ctrl.v1.GenerateUploadURLResponse. * Use `create(GenerateUploadURLResponseSchema)` to create a new message. */ -export const GenerateUploadURLResponseSchema: GenMessage = - /*@__PURE__*/ +export const GenerateUploadURLResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_build, 3); /** @@ -158,7 +151,7 @@ export const BuildService: GenService<{ methodKind: "unary"; input: typeof CreateBuildRequestSchema; output: typeof CreateBuildResponseSchema; - }; + }, /** * @generated from rpc ctrl.v1.BuildService.GenerateUploadURL */ @@ -166,5 +159,7 @@ export const BuildService: GenService<{ methodKind: "unary"; input: typeof GenerateUploadURLRequestSchema; output: typeof GenerateUploadURLResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_build, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_build, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/deployment_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/deployment_pb.ts index 2034cf6927..0b0c05f477 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/deployment_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/deployment_pb.ts @@ -2,18 +2,15 @@ // @generated from file ctrl/v1/deployment.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/deployment.proto. */ -export const file_ctrl_v1_deployment: GenFile = - /*@__PURE__*/ - fileDesc( - "ChhjdHJsL3YxL2RlcGxveW1lbnQucHJvdG8SB2N0cmwudjEimQIKF0NyZWF0ZURlcGxveW1lbnRSZXF1ZXN0EhIKCnByb2plY3RfaWQYAiABKAkSDgoGYnJhbmNoGAMgASgJEhgKEGVudmlyb25tZW50X3NsdWcYBCABKAkSLgoNYnVpbGRfY29udGV4dBgFIAEoCzIVLmN0cmwudjEuQnVpbGRDb250ZXh0SAASFgoMZG9ja2VyX2ltYWdlGAYgASgJSAASLwoKZ2l0X2NvbW1pdBgHIAEoCzIWLmN0cmwudjEuR2l0Q29tbWl0SW5mb0gBiAEBEhgKC2tleXNwYWNlX2lkGAggASgJSAKIAQFCCAoGc291cmNlQg0KC19naXRfY29tbWl0Qg4KDF9rZXlzcGFjZV9pZEoECAEQAiJcCgxCdWlsZENvbnRleHQSGgoSYnVpbGRfY29udGV4dF9wYXRoGAEgASgJEhwKD2RvY2tlcmZpbGVfcGF0aBgCIAEoCUgAiAEBQhIKEF9kb2NrZXJmaWxlX3BhdGgigAEKDUdpdENvbW1pdEluZm8SEgoKY29tbWl0X3NoYRgBIAEoCRIWCg5jb21taXRfbWVzc2FnZRgCIAEoCRIVCg1hdXRob3JfaGFuZGxlGAMgASgJEhkKEWF1dGhvcl9hdmF0YXJfdXJsGAQgASgJEhEKCXRpbWVzdGFtcBgFIAEoAyJcChhDcmVhdGVEZXBsb3ltZW50UmVzcG9uc2USFQoNZGVwbG95bWVudF9pZBgBIAEoCRIpCgZzdGF0dXMYAiABKA4yGS5jdHJsLnYxLkRlcGxveW1lbnRTdGF0dXMiLQoUR2V0RGVwbG95bWVudFJlcXVlc3QSFQoNZGVwbG95bWVudF9pZBgBIAEoCSJAChVHZXREZXBsb3ltZW50UmVzcG9uc2USJwoKZGVwbG95bWVudBgBIAEoCzITLmN0cmwudjEuRGVwbG95bWVudCKIBQoKRGVwbG95bWVudBIKCgJpZBgBIAEoCRIUCgx3b3Jrc3BhY2VfaWQYAiABKAkSEgoKcHJvamVjdF9pZBgDIAEoCRIWCg5lbnZpcm9ubWVudF9pZBgEIAEoCRIWCg5naXRfY29tbWl0X3NoYRgFIAEoCRISCgpnaXRfYnJhbmNoGAYgASgJEikKBnN0YXR1cxgHIAEoDjIZLmN0cmwudjEuRGVwbG95bWVudFN0YXR1cxIVCg1lcnJvcl9tZXNzYWdlGAggASgJEkwKFWVudmlyb25tZW50X3ZhcmlhYmxlcxgJIAMoCzItLmN0cmwudjEuRGVwbG95bWVudC5FbnZpcm9ubWVudFZhcmlhYmxlc0VudHJ5EiMKCHRvcG9sb2d5GAogASgLMhEuY3RybC52MS5Ub3BvbG9neRISCgpjcmVhdGVkX2F0GAsgASgDEhIKCnVwZGF0ZWRfYXQYDCABKAMSEQoJaG9zdG5hbWVzGA0gAygJEhcKD3Jvb3Rmc19pbWFnZV9pZBgOIAEoCRIQCghidWlsZF9pZBgPIAEoCRImCgVzdGVwcxgQIAMoCzIXLmN0cmwudjEuRGVwbG95bWVudFN0ZXASGgoSZ2l0X2NvbW1pdF9tZXNzYWdlGBEgASgJEiAKGGdpdF9jb21taXRfYXV0aG9yX2hhbmRsZRgSIAEoCRIkChxnaXRfY29tbWl0X2F1dGhvcl9hdmF0YXJfdXJsGBMgASgJEhwKFGdpdF9jb21taXRfdGltZXN0YW1wGBQgASgDGjsKGUVudmlyb25tZW50VmFyaWFibGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJcCg5EZXBsb3ltZW50U3RlcBIOCgZzdGF0dXMYASABKAkSDwoHbWVzc2FnZRgCIAEoCRIVCg1lcnJvcl9tZXNzYWdlGAMgASgJEhIKCmNyZWF0ZWRfYXQYBCABKAMipgEKCFRvcG9sb2d5EhYKDmNwdV9taWxsaWNvcmVzGAEgASgFEhEKCW1lbW9yeV9tYhgCIAEoBRIoCgdyZWdpb25zGAMgAygLMhcuY3RybC52MS5SZWdpb25hbENvbmZpZxIcChRpZGxlX3RpbWVvdXRfc2Vjb25kcxgEIAEoBRIZChFoZWFsdGhfY2hlY2tfcGF0aBgFIAEoCRIMCgRwb3J0GAYgASgFIk4KDlJlZ2lvbmFsQ29uZmlnEg4KBnJlZ2lvbhgBIAEoCRIVCg1taW5faW5zdGFuY2VzGAIgASgFEhUKDW1heF9pbnN0YW5jZXMYAyABKAUiTQoPUm9sbGJhY2tSZXF1ZXN0EhwKFHNvdXJjZV9kZXBsb3ltZW50X2lkGAEgASgJEhwKFHRhcmdldF9kZXBsb3ltZW50X2lkGAIgASgJIhIKEFJvbGxiYWNrUmVzcG9uc2UiLgoOUHJvbW90ZVJlcXVlc3QSHAoUdGFyZ2V0X2RlcGxveW1lbnRfaWQYASABKAkiEQoPUHJvbW90ZVJlc3BvbnNlKu8BChBEZXBsb3ltZW50U3RhdHVzEiEKHURFUExPWU1FTlRfU1RBVFVTX1VOU1BFQ0lGSUVEEAASHQoZREVQTE9ZTUVOVF9TVEFUVVNfUEVORElORxABEh4KGkRFUExPWU1FTlRfU1RBVFVTX0JVSUxESU5HEAISHwobREVQTE9ZTUVOVF9TVEFUVVNfREVQTE9ZSU5HEAMSHQoZREVQTE9ZTUVOVF9TVEFUVVNfTkVUV09SSxAEEhsKF0RFUExPWU1FTlRfU1RBVFVTX1JFQURZEAUSHAoYREVQTE9ZTUVOVF9TVEFUVVNfRkFJTEVEEAYqWgoKU291cmNlVHlwZRIbChdTT1VSQ0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD1NPVVJDRV9UWVBFX0dJVBABEhoKFlNPVVJDRV9UWVBFX0NMSV9VUExPQUQQAjLDAgoRRGVwbG95bWVudFNlcnZpY2USWQoQQ3JlYXRlRGVwbG95bWVudBIgLmN0cmwudjEuQ3JlYXRlRGVwbG95bWVudFJlcXVlc3QaIS5jdHJsLnYxLkNyZWF0ZURlcGxveW1lbnRSZXNwb25zZSIAElAKDUdldERlcGxveW1lbnQSHS5jdHJsLnYxLkdldERlcGxveW1lbnRSZXF1ZXN0Gh4uY3RybC52MS5HZXREZXBsb3ltZW50UmVzcG9uc2UiABJBCghSb2xsYmFjaxIYLmN0cmwudjEuUm9sbGJhY2tSZXF1ZXN0GhkuY3RybC52MS5Sb2xsYmFja1Jlc3BvbnNlIgASPgoHUHJvbW90ZRIXLmN0cmwudjEuUHJvbW90ZVJlcXVlc3QaGC5jdHJsLnYxLlByb21vdGVSZXNwb25zZSIAQpEBCgtjb20uY3RybC52MUIPRGVwbG95bWVudFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - ); +export const file_ctrl_v1_deployment: GenFile = /*@__PURE__*/ + fileDesc("ChhjdHJsL3YxL2RlcGxveW1lbnQucHJvdG8SB2N0cmwudjEimQIKF0NyZWF0ZURlcGxveW1lbnRSZXF1ZXN0EhIKCnByb2plY3RfaWQYAiABKAkSDgoGYnJhbmNoGAMgASgJEhgKEGVudmlyb25tZW50X3NsdWcYBCABKAkSLgoNYnVpbGRfY29udGV4dBgFIAEoCzIVLmN0cmwudjEuQnVpbGRDb250ZXh0SAASFgoMZG9ja2VyX2ltYWdlGAYgASgJSAASLwoKZ2l0X2NvbW1pdBgHIAEoCzIWLmN0cmwudjEuR2l0Q29tbWl0SW5mb0gBiAEBEhgKC2tleXNwYWNlX2lkGAggASgJSAKIAQFCCAoGc291cmNlQg0KC19naXRfY29tbWl0Qg4KDF9rZXlzcGFjZV9pZEoECAEQAiJcCgxCdWlsZENvbnRleHQSGgoSYnVpbGRfY29udGV4dF9wYXRoGAEgASgJEhwKD2RvY2tlcmZpbGVfcGF0aBgCIAEoCUgAiAEBQhIKEF9kb2NrZXJmaWxlX3BhdGgigAEKDUdpdENvbW1pdEluZm8SEgoKY29tbWl0X3NoYRgBIAEoCRIWCg5jb21taXRfbWVzc2FnZRgCIAEoCRIVCg1hdXRob3JfaGFuZGxlGAMgASgJEhkKEWF1dGhvcl9hdmF0YXJfdXJsGAQgASgJEhEKCXRpbWVzdGFtcBgFIAEoAyJcChhDcmVhdGVEZXBsb3ltZW50UmVzcG9uc2USFQoNZGVwbG95bWVudF9pZBgBIAEoCRIpCgZzdGF0dXMYAiABKA4yGS5jdHJsLnYxLkRlcGxveW1lbnRTdGF0dXMiLQoUR2V0RGVwbG95bWVudFJlcXVlc3QSFQoNZGVwbG95bWVudF9pZBgBIAEoCSJAChVHZXREZXBsb3ltZW50UmVzcG9uc2USJwoKZGVwbG95bWVudBgBIAEoCzITLmN0cmwudjEuRGVwbG95bWVudCKIBQoKRGVwbG95bWVudBIKCgJpZBgBIAEoCRIUCgx3b3Jrc3BhY2VfaWQYAiABKAkSEgoKcHJvamVjdF9pZBgDIAEoCRIWCg5lbnZpcm9ubWVudF9pZBgEIAEoCRIWCg5naXRfY29tbWl0X3NoYRgFIAEoCRISCgpnaXRfYnJhbmNoGAYgASgJEikKBnN0YXR1cxgHIAEoDjIZLmN0cmwudjEuRGVwbG95bWVudFN0YXR1cxIVCg1lcnJvcl9tZXNzYWdlGAggASgJEkwKFWVudmlyb25tZW50X3ZhcmlhYmxlcxgJIAMoCzItLmN0cmwudjEuRGVwbG95bWVudC5FbnZpcm9ubWVudFZhcmlhYmxlc0VudHJ5EiMKCHRvcG9sb2d5GAogASgLMhEuY3RybC52MS5Ub3BvbG9neRISCgpjcmVhdGVkX2F0GAsgASgDEhIKCnVwZGF0ZWRfYXQYDCABKAMSEQoJaG9zdG5hbWVzGA0gAygJEhcKD3Jvb3Rmc19pbWFnZV9pZBgOIAEoCRIQCghidWlsZF9pZBgPIAEoCRImCgVzdGVwcxgQIAMoCzIXLmN0cmwudjEuRGVwbG95bWVudFN0ZXASGgoSZ2l0X2NvbW1pdF9tZXNzYWdlGBEgASgJEiAKGGdpdF9jb21taXRfYXV0aG9yX2hhbmRsZRgSIAEoCRIkChxnaXRfY29tbWl0X2F1dGhvcl9hdmF0YXJfdXJsGBMgASgJEhwKFGdpdF9jb21taXRfdGltZXN0YW1wGBQgASgDGjsKGUVudmlyb25tZW50VmFyaWFibGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJcCg5EZXBsb3ltZW50U3RlcBIOCgZzdGF0dXMYASABKAkSDwoHbWVzc2FnZRgCIAEoCRIVCg1lcnJvcl9tZXNzYWdlGAMgASgJEhIKCmNyZWF0ZWRfYXQYBCABKAMipgEKCFRvcG9sb2d5EhYKDmNwdV9taWxsaWNvcmVzGAEgASgFEhEKCW1lbW9yeV9tYhgCIAEoBRIoCgdyZWdpb25zGAMgAygLMhcuY3RybC52MS5SZWdpb25hbENvbmZpZxIcChRpZGxlX3RpbWVvdXRfc2Vjb25kcxgEIAEoBRIZChFoZWFsdGhfY2hlY2tfcGF0aBgFIAEoCRIMCgRwb3J0GAYgASgFIk4KDlJlZ2lvbmFsQ29uZmlnEg4KBnJlZ2lvbhgBIAEoCRIVCg1taW5faW5zdGFuY2VzGAIgASgFEhUKDW1heF9pbnN0YW5jZXMYAyABKAUiTQoPUm9sbGJhY2tSZXF1ZXN0EhwKFHNvdXJjZV9kZXBsb3ltZW50X2lkGAEgASgJEhwKFHRhcmdldF9kZXBsb3ltZW50X2lkGAIgASgJIhIKEFJvbGxiYWNrUmVzcG9uc2UiLgoOUHJvbW90ZVJlcXVlc3QSHAoUdGFyZ2V0X2RlcGxveW1lbnRfaWQYASABKAkiEQoPUHJvbW90ZVJlc3BvbnNlKu8BChBEZXBsb3ltZW50U3RhdHVzEiEKHURFUExPWU1FTlRfU1RBVFVTX1VOU1BFQ0lGSUVEEAASHQoZREVQTE9ZTUVOVF9TVEFUVVNfUEVORElORxABEh4KGkRFUExPWU1FTlRfU1RBVFVTX0JVSUxESU5HEAISHwobREVQTE9ZTUVOVF9TVEFUVVNfREVQTE9ZSU5HEAMSHQoZREVQTE9ZTUVOVF9TVEFUVVNfTkVUV09SSxAEEhsKF0RFUExPWU1FTlRfU1RBVFVTX1JFQURZEAUSHAoYREVQTE9ZTUVOVF9TVEFUVVNfRkFJTEVEEAYqWgoKU291cmNlVHlwZRIbChdTT1VSQ0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD1NPVVJDRV9UWVBFX0dJVBABEhoKFlNPVVJDRV9UWVBFX0NMSV9VUExPQUQQAjLDAgoRRGVwbG95bWVudFNlcnZpY2USWQoQQ3JlYXRlRGVwbG95bWVudBIgLmN0cmwudjEuQ3JlYXRlRGVwbG95bWVudFJlcXVlc3QaIS5jdHJsLnYxLkNyZWF0ZURlcGxveW1lbnRSZXNwb25zZSIAElAKDUdldERlcGxveW1lbnQSHS5jdHJsLnYxLkdldERlcGxveW1lbnRSZXF1ZXN0Gh4uY3RybC52MS5HZXREZXBsb3ltZW50UmVzcG9uc2UiABJBCghSb2xsYmFjaxIYLmN0cmwudjEuUm9sbGJhY2tSZXF1ZXN0GhkuY3RybC52MS5Sb2xsYmFja1Jlc3BvbnNlIgASPgoHUHJvbW90ZRIXLmN0cmwudjEuUHJvbW90ZVJlcXVlc3QaGC5jdHJsLnYxLlByb21vdGVSZXNwb25zZSIAQpEBCgtjb20uY3RybC52MUIPRGVwbG95bWVudFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z"); /** * @generated from message ctrl.v1.CreateDeploymentRequest @@ -39,24 +36,21 @@ export type CreateDeploymentRequest = Message<"ctrl.v1.CreateDeploymentRequest"> * * @generated from oneof ctrl.v1.CreateDeploymentRequest.source */ - source: - | { - /** - * @generated from field: ctrl.v1.BuildContext build_context = 5; - */ - value: BuildContext; - case: "buildContext"; - } - | { - /** - * Prebuilt image reference - * - * @generated from field: string docker_image = 6; - */ - value: string; - case: "dockerImage"; - } - | { case: undefined; value?: undefined }; + source: { + /** + * @generated from field: ctrl.v1.BuildContext build_context = 5; + */ + value: BuildContext; + case: "buildContext"; + } | { + /** + * Prebuilt image reference + * + * @generated from field: string docker_image = 6; + */ + value: string; + case: "dockerImage"; + } | { case: undefined; value?: undefined }; /** * Git information @@ -77,8 +71,7 @@ export type CreateDeploymentRequest = Message<"ctrl.v1.CreateDeploymentRequest"> * Describes the message ctrl.v1.CreateDeploymentRequest. * Use `create(CreateDeploymentRequestSchema)` to create a new message. */ -export const CreateDeploymentRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateDeploymentRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 0); /** @@ -104,8 +97,7 @@ export type BuildContext = Message<"ctrl.v1.BuildContext"> & { * Describes the message ctrl.v1.BuildContext. * Use `create(BuildContextSchema)` to create a new message. */ -export const BuildContextSchema: GenMessage = - /*@__PURE__*/ +export const BuildContextSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 1); /** @@ -144,8 +136,7 @@ export type GitCommitInfo = Message<"ctrl.v1.GitCommitInfo"> & { * Describes the message ctrl.v1.GitCommitInfo. * Use `create(GitCommitInfoSchema)` to create a new message. */ -export const GitCommitInfoSchema: GenMessage = - /*@__PURE__*/ +export const GitCommitInfoSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 2); /** @@ -169,8 +160,7 @@ export type CreateDeploymentResponse = Message<"ctrl.v1.CreateDeploymentResponse * Describes the message ctrl.v1.CreateDeploymentResponse. * Use `create(CreateDeploymentResponseSchema)` to create a new message. */ -export const CreateDeploymentResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateDeploymentResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 3); /** @@ -187,8 +177,7 @@ export type GetDeploymentRequest = Message<"ctrl.v1.GetDeploymentRequest"> & { * Describes the message ctrl.v1.GetDeploymentRequest. * Use `create(GetDeploymentRequestSchema)` to create a new message. */ -export const GetDeploymentRequestSchema: GenMessage = - /*@__PURE__*/ +export const GetDeploymentRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 4); /** @@ -205,8 +194,7 @@ export type GetDeploymentResponse = Message<"ctrl.v1.GetDeploymentResponse"> & { * Describes the message ctrl.v1.GetDeploymentResponse. * Use `create(GetDeploymentResponseSchema)` to create a new message. */ -export const GetDeploymentResponseSchema: GenMessage = - /*@__PURE__*/ +export const GetDeploymentResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 5); /** @@ -342,8 +330,7 @@ export type Deployment = Message<"ctrl.v1.Deployment"> & { * Describes the message ctrl.v1.Deployment. * Use `create(DeploymentSchema)` to create a new message. */ -export const DeploymentSchema: GenMessage = - /*@__PURE__*/ +export const DeploymentSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 6); /** @@ -375,8 +362,7 @@ export type DeploymentStep = Message<"ctrl.v1.DeploymentStep"> & { * Describes the message ctrl.v1.DeploymentStep. * Use `create(DeploymentStepSchema)` to create a new message. */ -export const DeploymentStepSchema: GenMessage = - /*@__PURE__*/ +export const DeploymentStepSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 7); /** @@ -424,8 +410,7 @@ export type Topology = Message<"ctrl.v1.Topology"> & { * Describes the message ctrl.v1.Topology. * Use `create(TopologySchema)` to create a new message. */ -export const TopologySchema: GenMessage = - /*@__PURE__*/ +export const TopologySchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 8); /** @@ -452,8 +437,7 @@ export type RegionalConfig = Message<"ctrl.v1.RegionalConfig"> & { * Describes the message ctrl.v1.RegionalConfig. * Use `create(RegionalConfigSchema)` to create a new message. */ -export const RegionalConfigSchema: GenMessage = - /*@__PURE__*/ +export const RegionalConfigSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 9); /** @@ -475,21 +459,20 @@ export type RollbackRequest = Message<"ctrl.v1.RollbackRequest"> & { * Describes the message ctrl.v1.RollbackRequest. * Use `create(RollbackRequestSchema)` to create a new message. */ -export const RollbackRequestSchema: GenMessage = - /*@__PURE__*/ +export const RollbackRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 10); /** * @generated from message ctrl.v1.RollbackResponse */ -export type RollbackResponse = Message<"ctrl.v1.RollbackResponse"> & {}; +export type RollbackResponse = Message<"ctrl.v1.RollbackResponse"> & { +}; /** * Describes the message ctrl.v1.RollbackResponse. * Use `create(RollbackResponseSchema)` to create a new message. */ -export const RollbackResponseSchema: GenMessage = - /*@__PURE__*/ +export const RollbackResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 11); /** @@ -506,21 +489,20 @@ export type PromoteRequest = Message<"ctrl.v1.PromoteRequest"> & { * Describes the message ctrl.v1.PromoteRequest. * Use `create(PromoteRequestSchema)` to create a new message. */ -export const PromoteRequestSchema: GenMessage = - /*@__PURE__*/ +export const PromoteRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 12); /** * @generated from message ctrl.v1.PromoteResponse */ -export type PromoteResponse = Message<"ctrl.v1.PromoteResponse"> & {}; +export type PromoteResponse = Message<"ctrl.v1.PromoteResponse"> & { +}; /** * Describes the message ctrl.v1.PromoteResponse. * Use `create(PromoteResponseSchema)` to create a new message. */ -export const PromoteResponseSchema: GenMessage = - /*@__PURE__*/ +export const PromoteResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_deployment, 13); /** @@ -568,8 +550,7 @@ export enum DeploymentStatus { /** * Describes the enum ctrl.v1.DeploymentStatus. */ -export const DeploymentStatusSchema: GenEnum = - /*@__PURE__*/ +export const DeploymentStatusSchema: GenEnum = /*@__PURE__*/ enumDesc(file_ctrl_v1_deployment, 0); /** @@ -597,8 +578,7 @@ export enum SourceType { /** * Describes the enum ctrl.v1.SourceType. */ -export const SourceTypeSchema: GenEnum = - /*@__PURE__*/ +export const SourceTypeSchema: GenEnum = /*@__PURE__*/ enumDesc(file_ctrl_v1_deployment, 1); /** @@ -614,7 +594,7 @@ export const DeploymentService: GenService<{ methodKind: "unary"; input: typeof CreateDeploymentRequestSchema; output: typeof CreateDeploymentResponseSchema; - }; + }, /** * Get deployment details * @@ -624,7 +604,7 @@ export const DeploymentService: GenService<{ methodKind: "unary"; input: typeof GetDeploymentRequestSchema; output: typeof GetDeploymentResponseSchema; - }; + }, /** * Reassign the sticky domains of the projects live deployment to the target deployment * @@ -634,7 +614,7 @@ export const DeploymentService: GenService<{ methodKind: "unary"; input: typeof RollbackRequestSchema; output: typeof RollbackResponseSchema; - }; + }, /** * Promote the deployment to the live environment * @@ -644,5 +624,7 @@ export const DeploymentService: GenService<{ methodKind: "unary"; input: typeof PromoteRequestSchema; output: typeof PromoteResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_deployment, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_deployment, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/environment_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/environment_pb.ts index 563e2a6641..32f234bc2f 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/environment_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/environment_pb.ts @@ -2,18 +2,15 @@ // @generated from file ctrl/v1/environment.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/environment.proto. */ -export const file_ctrl_v1_environment: GenFile = - /*@__PURE__*/ - fileDesc( - "ChljdHJsL3YxL2Vudmlyb25tZW50LnByb3RvEgdjdHJsLnYxInkKGENyZWF0ZUVudmlyb25tZW50UmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEgwKBHNsdWcYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSJgoEdHlwZRgEIAEoDjIYLmN0cmwudjEuRW52aXJvbm1lbnRUeXBlIicKGUNyZWF0ZUVudmlyb25tZW50UmVzcG9uc2USCgoCaWQYASABKAkqlAEKD0Vudmlyb25tZW50VHlwZRIgChxFTlZJUk9OTUVOVF9UWVBFX1VOU1BFQ0lGSUVEEAASIAocRU5WSVJPTk1FTlRfVFlQRV9ERVZFTE9QTUVOVBABEhwKGEVOVklST05NRU5UX1RZUEVfUFJFVklFVxACEh8KG0VOVklST05NRU5UX1RZUEVfUFJPRFVDVElPThADMnIKEkVudmlyb25tZW50U2VydmljZRJcChFDcmVhdGVFbnZpcm9ubWVudBIhLmN0cmwudjEuQ3JlYXRlRW52aXJvbm1lbnRSZXF1ZXN0GiIuY3RybC52MS5DcmVhdGVFbnZpcm9ubWVudFJlc3BvbnNlIgBCkgEKC2NvbS5jdHJsLnYxQhBFbnZpcm9ubWVudFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - ); +export const file_ctrl_v1_environment: GenFile = /*@__PURE__*/ + fileDesc("ChljdHJsL3YxL2Vudmlyb25tZW50LnByb3RvEgdjdHJsLnYxInkKGENyZWF0ZUVudmlyb25tZW50UmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEgwKBHNsdWcYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSJgoEdHlwZRgEIAEoDjIYLmN0cmwudjEuRW52aXJvbm1lbnRUeXBlIicKGUNyZWF0ZUVudmlyb25tZW50UmVzcG9uc2USCgoCaWQYASABKAkqlAEKD0Vudmlyb25tZW50VHlwZRIgChxFTlZJUk9OTUVOVF9UWVBFX1VOU1BFQ0lGSUVEEAASIAocRU5WSVJPTk1FTlRfVFlQRV9ERVZFTE9QTUVOVBABEhwKGEVOVklST05NRU5UX1RZUEVfUFJFVklFVxACEh8KG0VOVklST05NRU5UX1RZUEVfUFJPRFVDVElPThADMnIKEkVudmlyb25tZW50U2VydmljZRJcChFDcmVhdGVFbnZpcm9ubWVudBIhLmN0cmwudjEuQ3JlYXRlRW52aXJvbm1lbnRSZXF1ZXN0GiIuY3RybC52MS5DcmVhdGVFbnZpcm9ubWVudFJlc3BvbnNlIgBCkgEKC2NvbS5jdHJsLnYxQhBFbnZpcm9ubWVudFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z"); /** * @generated from message ctrl.v1.CreateEnvironmentRequest @@ -44,8 +41,7 @@ export type CreateEnvironmentRequest = Message<"ctrl.v1.CreateEnvironmentRequest * Describes the message ctrl.v1.CreateEnvironmentRequest. * Use `create(CreateEnvironmentRequestSchema)` to create a new message. */ -export const CreateEnvironmentRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateEnvironmentRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_environment, 0); /** @@ -62,8 +58,7 @@ export type CreateEnvironmentResponse = Message<"ctrl.v1.CreateEnvironmentRespon * Describes the message ctrl.v1.CreateEnvironmentResponse. * Use `create(CreateEnvironmentResponseSchema)` to create a new message. */ -export const CreateEnvironmentResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateEnvironmentResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_environment, 1); /** @@ -94,8 +89,7 @@ export enum EnvironmentType { /** * Describes the enum ctrl.v1.EnvironmentType. */ -export const EnvironmentTypeSchema: GenEnum = - /*@__PURE__*/ +export const EnvironmentTypeSchema: GenEnum = /*@__PURE__*/ enumDesc(file_ctrl_v1_environment, 0); /** @@ -109,5 +103,7 @@ export const EnvironmentService: GenService<{ methodKind: "unary"; input: typeof CreateEnvironmentRequestSchema; output: typeof CreateEnvironmentResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_environment, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_environment, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/openapi_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/openapi_pb.ts index 2a83231830..a83bad8042 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/openapi_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/openapi_pb.ts @@ -2,18 +2,15 @@ // @generated from file ctrl/v1/openapi.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/openapi.proto. */ -export const file_ctrl_v1_openapi: GenFile = - /*@__PURE__*/ - fileDesc( - "ChVjdHJsL3YxL29wZW5hcGkucHJvdG8SB2N0cmwudjEiTQoVR2V0T3BlbkFwaURpZmZSZXF1ZXN0EhkKEW9sZF9kZXBsb3ltZW50X2lkGAEgASgJEhkKEW5ld19kZXBsb3ltZW50X2lkGAIgASgJIoYBCg5DaGFuZ2Vsb2dFbnRyeRIKCgJpZBgBIAEoCRIMCgR0ZXh0GAIgASgJEg0KBWxldmVsGAMgASgFEhEKCW9wZXJhdGlvbhgEIAEoCRIZCgxvcGVyYXRpb25faWQYBSABKAlIAIgBARIMCgRwYXRoGAYgASgJQg8KDV9vcGVyYXRpb25faWQiQgoLRGlmZlN1bW1hcnkSDAoEZGlmZhgBIAEoCBIlCgdkZXRhaWxzGAIgASgLMhQuY3RybC52MS5EaWZmRGV0YWlscyJ/CgtEaWZmRGV0YWlscxImCgllbmRwb2ludHMYASABKAsyEy5jdHJsLnYxLkRpZmZDb3VudHMSIgoFcGF0aHMYAiABKAsyEy5jdHJsLnYxLkRpZmZDb3VudHMSJAoHc2NoZW1hcxgDIAEoCzITLmN0cmwudjEuRGlmZkNvdW50cyI+CgpEaWZmQ291bnRzEg0KBWFkZGVkGAEgASgFEg8KB2RlbGV0ZWQYAiABKAUSEAoIbW9kaWZpZWQYAyABKAUihwEKFkdldE9wZW5BcGlEaWZmUmVzcG9uc2USJQoHc3VtbWFyeRgBIAEoCzIULmN0cmwudjEuRGlmZlN1bW1hcnkSHAoUaGFzX2JyZWFraW5nX2NoYW5nZXMYAiABKAgSKAoHY2hhbmdlcxgDIAMoCzIXLmN0cmwudjEuQ2hhbmdlbG9nRW50cnkyZQoOT3BlbkFwaVNlcnZpY2USUwoOR2V0T3BlbkFwaURpZmYSHi5jdHJsLnYxLkdldE9wZW5BcGlEaWZmUmVxdWVzdBofLmN0cmwudjEuR2V0T3BlbkFwaURpZmZSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMT3BlbmFwaVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - ); +export const file_ctrl_v1_openapi: GenFile = /*@__PURE__*/ + fileDesc("ChVjdHJsL3YxL29wZW5hcGkucHJvdG8SB2N0cmwudjEiTQoVR2V0T3BlbkFwaURpZmZSZXF1ZXN0EhkKEW9sZF9kZXBsb3ltZW50X2lkGAEgASgJEhkKEW5ld19kZXBsb3ltZW50X2lkGAIgASgJIoYBCg5DaGFuZ2Vsb2dFbnRyeRIKCgJpZBgBIAEoCRIMCgR0ZXh0GAIgASgJEg0KBWxldmVsGAMgASgFEhEKCW9wZXJhdGlvbhgEIAEoCRIZCgxvcGVyYXRpb25faWQYBSABKAlIAIgBARIMCgRwYXRoGAYgASgJQg8KDV9vcGVyYXRpb25faWQiQgoLRGlmZlN1bW1hcnkSDAoEZGlmZhgBIAEoCBIlCgdkZXRhaWxzGAIgASgLMhQuY3RybC52MS5EaWZmRGV0YWlscyJ/CgtEaWZmRGV0YWlscxImCgllbmRwb2ludHMYASABKAsyEy5jdHJsLnYxLkRpZmZDb3VudHMSIgoFcGF0aHMYAiABKAsyEy5jdHJsLnYxLkRpZmZDb3VudHMSJAoHc2NoZW1hcxgDIAEoCzITLmN0cmwudjEuRGlmZkNvdW50cyI+CgpEaWZmQ291bnRzEg0KBWFkZGVkGAEgASgFEg8KB2RlbGV0ZWQYAiABKAUSEAoIbW9kaWZpZWQYAyABKAUihwEKFkdldE9wZW5BcGlEaWZmUmVzcG9uc2USJQoHc3VtbWFyeRgBIAEoCzIULmN0cmwudjEuRGlmZlN1bW1hcnkSHAoUaGFzX2JyZWFraW5nX2NoYW5nZXMYAiABKAgSKAoHY2hhbmdlcxgDIAMoCzIXLmN0cmwudjEuQ2hhbmdlbG9nRW50cnkyZQoOT3BlbkFwaVNlcnZpY2USUwoOR2V0T3BlbkFwaURpZmYSHi5jdHJsLnYxLkdldE9wZW5BcGlEaWZmUmVxdWVzdBofLmN0cmwudjEuR2V0T3BlbkFwaURpZmZSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMT3BlbmFwaVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z"); /** * @generated from message ctrl.v1.GetOpenApiDiffRequest @@ -34,8 +31,7 @@ export type GetOpenApiDiffRequest = Message<"ctrl.v1.GetOpenApiDiffRequest"> & { * Describes the message ctrl.v1.GetOpenApiDiffRequest. * Use `create(GetOpenApiDiffRequestSchema)` to create a new message. */ -export const GetOpenApiDiffRequestSchema: GenMessage = - /*@__PURE__*/ +export const GetOpenApiDiffRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 0); /** @@ -77,8 +73,7 @@ export type ChangelogEntry = Message<"ctrl.v1.ChangelogEntry"> & { * Describes the message ctrl.v1.ChangelogEntry. * Use `create(ChangelogEntrySchema)` to create a new message. */ -export const ChangelogEntrySchema: GenMessage = - /*@__PURE__*/ +export const ChangelogEntrySchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 1); /** @@ -100,8 +95,7 @@ export type DiffSummary = Message<"ctrl.v1.DiffSummary"> & { * Describes the message ctrl.v1.DiffSummary. * Use `create(DiffSummarySchema)` to create a new message. */ -export const DiffSummarySchema: GenMessage = - /*@__PURE__*/ +export const DiffSummarySchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 2); /** @@ -128,8 +122,7 @@ export type DiffDetails = Message<"ctrl.v1.DiffDetails"> & { * Describes the message ctrl.v1.DiffDetails. * Use `create(DiffDetailsSchema)` to create a new message. */ -export const DiffDetailsSchema: GenMessage = - /*@__PURE__*/ +export const DiffDetailsSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 3); /** @@ -156,8 +149,7 @@ export type DiffCounts = Message<"ctrl.v1.DiffCounts"> & { * Describes the message ctrl.v1.DiffCounts. * Use `create(DiffCountsSchema)` to create a new message. */ -export const DiffCountsSchema: GenMessage = - /*@__PURE__*/ +export const DiffCountsSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 4); /** @@ -184,8 +176,7 @@ export type GetOpenApiDiffResponse = Message<"ctrl.v1.GetOpenApiDiffResponse"> & * Describes the message ctrl.v1.GetOpenApiDiffResponse. * Use `create(GetOpenApiDiffResponseSchema)` to create a new message. */ -export const GetOpenApiDiffResponseSchema: GenMessage = - /*@__PURE__*/ +export const GetOpenApiDiffResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_openapi, 5); /** @@ -199,5 +190,7 @@ export const OpenApiService: GenService<{ methodKind: "unary"; input: typeof GetOpenApiDiffRequestSchema; output: typeof GetOpenApiDiffResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_openapi, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_openapi, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/project_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/project_pb.ts index 47b868be0b..2307f04b81 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/project_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/project_pb.ts @@ -2,18 +2,15 @@ // @generated from file ctrl/v1/project.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/project.proto. */ -export const file_ctrl_v1_project: GenFile = - /*@__PURE__*/ - fileDesc( - "ChVjdHJsL3YxL3Byb2plY3QucHJvdG8SB2N0cmwudjEiYAoUQ3JlYXRlUHJvamVjdFJlcXVlc3QSFAoMd29ya3NwYWNlX2lkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEc2x1ZxgDIAEoCRIWCg5naXRfcmVwb3NpdG9yeRgEIAEoCSIjChVDcmVhdGVQcm9qZWN0UmVzcG9uc2USCgoCaWQYASABKAkyYgoOUHJvamVjdFNlcnZpY2USUAoNQ3JlYXRlUHJvamVjdBIdLmN0cmwudjEuQ3JlYXRlUHJvamVjdFJlcXVlc3QaHi5jdHJsLnYxLkNyZWF0ZVByb2plY3RSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMUHJvamVjdFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - ); +export const file_ctrl_v1_project: GenFile = /*@__PURE__*/ + fileDesc("ChVjdHJsL3YxL3Byb2plY3QucHJvdG8SB2N0cmwudjEiYAoUQ3JlYXRlUHJvamVjdFJlcXVlc3QSFAoMd29ya3NwYWNlX2lkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEc2x1ZxgDIAEoCRIWCg5naXRfcmVwb3NpdG9yeRgEIAEoCSIjChVDcmVhdGVQcm9qZWN0UmVzcG9uc2USCgoCaWQYASABKAkyYgoOUHJvamVjdFNlcnZpY2USUAoNQ3JlYXRlUHJvamVjdBIdLmN0cmwudjEuQ3JlYXRlUHJvamVjdFJlcXVlc3QaHi5jdHJsLnYxLkNyZWF0ZVByb2plY3RSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMUHJvamVjdFByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z"); /** * @generated from message ctrl.v1.CreateProjectRequest @@ -44,8 +41,7 @@ export type CreateProjectRequest = Message<"ctrl.v1.CreateProjectRequest"> & { * Describes the message ctrl.v1.CreateProjectRequest. * Use `create(CreateProjectRequestSchema)` to create a new message. */ -export const CreateProjectRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateProjectRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_project, 0); /** @@ -62,8 +58,7 @@ export type CreateProjectResponse = Message<"ctrl.v1.CreateProjectResponse"> & { * Describes the message ctrl.v1.CreateProjectResponse. * Use `create(CreateProjectResponseSchema)` to create a new message. */ -export const CreateProjectResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateProjectResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_project, 1); /** @@ -77,5 +72,7 @@ export const ProjectService: GenService<{ methodKind: "unary"; input: typeof CreateProjectRequestSchema; output: typeof CreateProjectResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_project, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_project, 0); + diff --git a/apps/dashboard/gen/proto/ctrl/v1/service_pb.ts b/apps/dashboard/gen/proto/ctrl/v1/service_pb.ts index dc1c3038c4..bb90f20d71 100644 --- a/apps/dashboard/gen/proto/ctrl/v1/service_pb.ts +++ b/apps/dashboard/gen/proto/ctrl/v1/service_pb.ts @@ -2,30 +2,27 @@ // @generated from file ctrl/v1/service.proto (package ctrl.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file ctrl/v1/service.proto. */ -export const file_ctrl_v1_service: GenFile = - /*@__PURE__*/ - fileDesc( - "ChVjdHJsL3YxL3NlcnZpY2UucHJvdG8SB2N0cmwudjEiEQoPTGl2ZW5lc3NSZXF1ZXN0IkgKEExpdmVuZXNzUmVzcG9uc2USDgoGc3RhdHVzGAEgASgJEg8KB3ZlcnNpb24YAiABKAkSEwoLaW5zdGFuY2VfaWQYAyABKAkyUAoLQ3RybFNlcnZpY2USQQoITGl2ZW5lc3MSGC5jdHJsLnYxLkxpdmVuZXNzUmVxdWVzdBoZLmN0cmwudjEuTGl2ZW5lc3NSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMU2VydmljZVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z", - ); +export const file_ctrl_v1_service: GenFile = /*@__PURE__*/ + fileDesc("ChVjdHJsL3YxL3NlcnZpY2UucHJvdG8SB2N0cmwudjEiEQoPTGl2ZW5lc3NSZXF1ZXN0IkgKEExpdmVuZXNzUmVzcG9uc2USDgoGc3RhdHVzGAEgASgJEg8KB3ZlcnNpb24YAiABKAkSEwoLaW5zdGFuY2VfaWQYAyABKAkyUAoLQ3RybFNlcnZpY2USQQoITGl2ZW5lc3MSGC5jdHJsLnYxLkxpdmVuZXNzUmVxdWVzdBoZLmN0cmwudjEuTGl2ZW5lc3NSZXNwb25zZSIAQo4BCgtjb20uY3RybC52MUIMU2VydmljZVByb3RvUAFaNGdpdGh1Yi5jb20vdW5rZXllZC91bmtleS9nby9nZW4vcHJvdG8vY3RybC92MTtjdHJsdjGiAgNDWFiqAgdDdHJsLlYxygIHQ3RybFxWMeICE0N0cmxcVjFcR1BCTWV0YWRhdGHqAghDdHJsOjpWMWIGcHJvdG8z"); /** * @generated from message ctrl.v1.LivenessRequest */ -export type LivenessRequest = Message<"ctrl.v1.LivenessRequest"> & {}; +export type LivenessRequest = Message<"ctrl.v1.LivenessRequest"> & { +}; /** * Describes the message ctrl.v1.LivenessRequest. * Use `create(LivenessRequestSchema)` to create a new message. */ -export const LivenessRequestSchema: GenMessage = - /*@__PURE__*/ +export const LivenessRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_service, 0); /** @@ -52,8 +49,7 @@ export type LivenessResponse = Message<"ctrl.v1.LivenessResponse"> & { * Describes the message ctrl.v1.LivenessResponse. * Use `create(LivenessResponseSchema)` to create a new message. */ -export const LivenessResponseSchema: GenMessage = - /*@__PURE__*/ +export const LivenessResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_ctrl_v1_service, 1); /** @@ -67,5 +63,7 @@ export const CtrlService: GenService<{ methodKind: "unary"; input: typeof LivenessRequestSchema; output: typeof LivenessResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_ctrl_v1_service, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_ctrl_v1_service, 0); + diff --git a/apps/dashboard/gen/proto/krane/v1/gateway_pb.ts b/apps/dashboard/gen/proto/krane/v1/gateway_pb.ts index ed675d8066..78350344a4 100644 --- a/apps/dashboard/gen/proto/krane/v1/gateway_pb.ts +++ b/apps/dashboard/gen/proto/krane/v1/gateway_pb.ts @@ -2,18 +2,15 @@ // @generated from file krane/v1/gateway.proto (package krane.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file krane/v1/gateway.proto. */ -export const file_krane_v1_gateway: GenFile = - /*@__PURE__*/ - fileDesc( - "ChZrcmFuZS92MS9nYXRld2F5LnByb3RvEghrcmFuZS52MSKfAQoOR2F0ZXdheVJlcXVlc3QSEQoJbmFtZXNwYWNlGAEgASgJEhQKDHdvcmtzcGFjZV9pZBgCIAEoCRISCgpnYXRld2F5X2lkGAMgASgJEg0KBWltYWdlGAQgASgJEhAKCHJlcGxpY2FzGAUgASgNEhYKDmNwdV9taWxsaWNvcmVzGAYgASgNEhcKD21lbW9yeV9zaXplX21pYhgHIAEoBCJBChRDcmVhdGVHYXRld2F5UmVxdWVzdBIpCgdnYXRld2F5GAEgASgLMhgua3JhbmUudjEuR2F0ZXdheVJlcXVlc3QiQAoVQ3JlYXRlR2F0ZXdheVJlc3BvbnNlEicKBnN0YXR1cxgBIAEoDjIXLmtyYW5lLnYxLkdhdGV3YXlTdGF0dXMiQQoUVXBkYXRlR2F0ZXdheVJlcXVlc3QSKQoHZ2F0ZXdheRgBIAEoCzIYLmtyYW5lLnYxLkdhdGV3YXlSZXF1ZXN0IigKFVVwZGF0ZUdhdGV3YXlSZXNwb25zZRIPCgdwb2RfaWRzGAEgAygJIj0KFERlbGV0ZUdhdGV3YXlSZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCRISCgpnYXRld2F5X2lkGAIgASgJIhcKFURlbGV0ZUdhdGV3YXlSZXNwb25zZSI6ChFHZXRHYXRld2F5UmVxdWVzdBIRCgluYW1lc3BhY2UYASABKAkSEgoKZ2F0ZXdheV9pZBgCIAEoCSJTChJHZXRHYXRld2F5UmVzcG9uc2USDwoHYWRkcmVzcxgBIAEoCRIsCglpbnN0YW5jZXMYAiADKAsyGS5rcmFuZS52MS5HYXRld2F5SW5zdGFuY2UiRgoPR2F0ZXdheUluc3RhbmNlEgoKAmlkGAEgASgJEicKBnN0YXR1cxgCIAEoDjIXLmtyYW5lLnYxLkdhdGV3YXlTdGF0dXMqhwEKDUdhdGV3YXlTdGF0dXMSHgoaR0FURVdBWV9TVEFUVVNfVU5TUEVDSUZJRUQQABIaChZHQVRFV0FZX1NUQVRVU19QRU5ESU5HEAESGgoWR0FURVdBWV9TVEFUVVNfUlVOTklORxACEh4KGkdBVEVXQVlfU1RBVFVTX1RFUk1JTkFUSU5HEAMy/QEKDkdhdGV3YXlTZXJ2aWNlElAKDUNyZWF0ZUdhdGV3YXkSHi5rcmFuZS52MS5DcmVhdGVHYXRld2F5UmVxdWVzdBofLmtyYW5lLnYxLkNyZWF0ZUdhdGV3YXlSZXNwb25zZRJHCgpHZXRHYXRld2F5Ehsua3JhbmUudjEuR2V0R2F0ZXdheVJlcXVlc3QaHC5rcmFuZS52MS5HZXRHYXRld2F5UmVzcG9uc2USUAoNRGVsZXRlR2F0ZXdheRIeLmtyYW5lLnYxLkRlbGV0ZUdhdGV3YXlSZXF1ZXN0Gh8ua3JhbmUudjEuRGVsZXRlR2F0ZXdheVJlc3BvbnNlQpUBCgxjb20ua3JhbmUudjFCDEdhdGV3YXlQcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2tyYW5lL3YxO2tyYW5ldjGiAgNLWFiqAghLcmFuZS5WMcoCCEtyYW5lXFYx4gIUS3JhbmVcVjFcR1BCTWV0YWRhdGHqAglLcmFuZTo6VjFiBnByb3RvMw", - ); +export const file_krane_v1_gateway: GenFile = /*@__PURE__*/ + fileDesc("ChZrcmFuZS92MS9nYXRld2F5LnByb3RvEghrcmFuZS52MSKfAQoOR2F0ZXdheVJlcXVlc3QSEQoJbmFtZXNwYWNlGAEgASgJEhQKDHdvcmtzcGFjZV9pZBgCIAEoCRISCgpnYXRld2F5X2lkGAMgASgJEg0KBWltYWdlGAQgASgJEhAKCHJlcGxpY2FzGAUgASgNEhYKDmNwdV9taWxsaWNvcmVzGAYgASgNEhcKD21lbW9yeV9zaXplX21pYhgHIAEoBCJBChRDcmVhdGVHYXRld2F5UmVxdWVzdBIpCgdnYXRld2F5GAEgASgLMhgua3JhbmUudjEuR2F0ZXdheVJlcXVlc3QiQAoVQ3JlYXRlR2F0ZXdheVJlc3BvbnNlEicKBnN0YXR1cxgBIAEoDjIXLmtyYW5lLnYxLkdhdGV3YXlTdGF0dXMiQQoUVXBkYXRlR2F0ZXdheVJlcXVlc3QSKQoHZ2F0ZXdheRgBIAEoCzIYLmtyYW5lLnYxLkdhdGV3YXlSZXF1ZXN0IigKFVVwZGF0ZUdhdGV3YXlSZXNwb25zZRIPCgdwb2RfaWRzGAEgAygJIj0KFERlbGV0ZUdhdGV3YXlSZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCRISCgpnYXRld2F5X2lkGAIgASgJIhcKFURlbGV0ZUdhdGV3YXlSZXNwb25zZSI6ChFHZXRHYXRld2F5UmVxdWVzdBIRCgluYW1lc3BhY2UYASABKAkSEgoKZ2F0ZXdheV9pZBgCIAEoCSJTChJHZXRHYXRld2F5UmVzcG9uc2USDwoHYWRkcmVzcxgBIAEoCRIsCglpbnN0YW5jZXMYAiADKAsyGS5rcmFuZS52MS5HYXRld2F5SW5zdGFuY2UiRgoPR2F0ZXdheUluc3RhbmNlEgoKAmlkGAEgASgJEicKBnN0YXR1cxgCIAEoDjIXLmtyYW5lLnYxLkdhdGV3YXlTdGF0dXMqhwEKDUdhdGV3YXlTdGF0dXMSHgoaR0FURVdBWV9TVEFUVVNfVU5TUEVDSUZJRUQQABIaChZHQVRFV0FZX1NUQVRVU19QRU5ESU5HEAESGgoWR0FURVdBWV9TVEFUVVNfUlVOTklORxACEh4KGkdBVEVXQVlfU1RBVFVTX1RFUk1JTkFUSU5HEAMy/QEKDkdhdGV3YXlTZXJ2aWNlElAKDUNyZWF0ZUdhdGV3YXkSHi5rcmFuZS52MS5DcmVhdGVHYXRld2F5UmVxdWVzdBofLmtyYW5lLnYxLkNyZWF0ZUdhdGV3YXlSZXNwb25zZRJHCgpHZXRHYXRld2F5Ehsua3JhbmUudjEuR2V0R2F0ZXdheVJlcXVlc3QaHC5rcmFuZS52MS5HZXRHYXRld2F5UmVzcG9uc2USUAoNRGVsZXRlR2F0ZXdheRIeLmtyYW5lLnYxLkRlbGV0ZUdhdGV3YXlSZXF1ZXN0Gh8ua3JhbmUudjEuRGVsZXRlR2F0ZXdheVJlc3BvbnNlQpUBCgxjb20ua3JhbmUudjFCDEdhdGV3YXlQcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL2tyYW5lL3YxO2tyYW5ldjGiAgNLWFiqAghLcmFuZS5WMcoCCEtyYW5lXFYx4gIUS3JhbmVcVjFcR1BCTWV0YWRhdGHqAglLcmFuZTo6VjFiBnByb3RvMw"); /** * @generated from message krane.v1.GatewayRequest @@ -59,8 +56,7 @@ export type GatewayRequest = Message<"krane.v1.GatewayRequest"> & { * Describes the message krane.v1.GatewayRequest. * Use `create(GatewayRequestSchema)` to create a new message. */ -export const GatewayRequestSchema: GenMessage = - /*@__PURE__*/ +export const GatewayRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 0); /** @@ -77,8 +73,7 @@ export type CreateGatewayRequest = Message<"krane.v1.CreateGatewayRequest"> & { * Describes the message krane.v1.CreateGatewayRequest. * Use `create(CreateGatewayRequestSchema)` to create a new message. */ -export const CreateGatewayRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateGatewayRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 1); /** @@ -95,8 +90,7 @@ export type CreateGatewayResponse = Message<"krane.v1.CreateGatewayResponse"> & * Describes the message krane.v1.CreateGatewayResponse. * Use `create(CreateGatewayResponseSchema)` to create a new message. */ -export const CreateGatewayResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateGatewayResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 2); /** @@ -113,8 +107,7 @@ export type UpdateGatewayRequest = Message<"krane.v1.UpdateGatewayRequest"> & { * Describes the message krane.v1.UpdateGatewayRequest. * Use `create(UpdateGatewayRequestSchema)` to create a new message. */ -export const UpdateGatewayRequestSchema: GenMessage = - /*@__PURE__*/ +export const UpdateGatewayRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 3); /** @@ -131,8 +124,7 @@ export type UpdateGatewayResponse = Message<"krane.v1.UpdateGatewayResponse"> & * Describes the message krane.v1.UpdateGatewayResponse. * Use `create(UpdateGatewayResponseSchema)` to create a new message. */ -export const UpdateGatewayResponseSchema: GenMessage = - /*@__PURE__*/ +export const UpdateGatewayResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 4); /** @@ -154,21 +146,20 @@ export type DeleteGatewayRequest = Message<"krane.v1.DeleteGatewayRequest"> & { * Describes the message krane.v1.DeleteGatewayRequest. * Use `create(DeleteGatewayRequestSchema)` to create a new message. */ -export const DeleteGatewayRequestSchema: GenMessage = - /*@__PURE__*/ +export const DeleteGatewayRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 5); /** * @generated from message krane.v1.DeleteGatewayResponse */ -export type DeleteGatewayResponse = Message<"krane.v1.DeleteGatewayResponse"> & {}; +export type DeleteGatewayResponse = Message<"krane.v1.DeleteGatewayResponse"> & { +}; /** * Describes the message krane.v1.DeleteGatewayResponse. * Use `create(DeleteGatewayResponseSchema)` to create a new message. */ -export const DeleteGatewayResponseSchema: GenMessage = - /*@__PURE__*/ +export const DeleteGatewayResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 6); /** @@ -190,8 +181,7 @@ export type GetGatewayRequest = Message<"krane.v1.GetGatewayRequest"> & { * Describes the message krane.v1.GetGatewayRequest. * Use `create(GetGatewayRequestSchema)` to create a new message. */ -export const GetGatewayRequestSchema: GenMessage = - /*@__PURE__*/ +export const GetGatewayRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 7); /** @@ -213,8 +203,7 @@ export type GetGatewayResponse = Message<"krane.v1.GetGatewayResponse"> & { * Describes the message krane.v1.GetGatewayResponse. * Use `create(GetGatewayResponseSchema)` to create a new message. */ -export const GetGatewayResponseSchema: GenMessage = - /*@__PURE__*/ +export const GetGatewayResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 8); /** @@ -236,8 +225,7 @@ export type GatewayInstance = Message<"krane.v1.GatewayInstance"> & { * Describes the message krane.v1.GatewayInstance. * Use `create(GatewayInstanceSchema)` to create a new message. */ -export const GatewayInstanceSchema: GenMessage = - /*@__PURE__*/ +export const GatewayInstanceSchema: GenMessage = /*@__PURE__*/ messageDesc(file_krane_v1_gateway, 9); /** @@ -274,8 +262,7 @@ export enum GatewayStatus { /** * Describes the enum krane.v1.GatewayStatus. */ -export const GatewayStatusSchema: GenEnum = - /*@__PURE__*/ +export const GatewayStatusSchema: GenEnum = /*@__PURE__*/ enumDesc(file_krane_v1_gateway, 0); /** @@ -291,7 +278,7 @@ export const GatewayService: GenService<{ methodKind: "unary"; input: typeof CreateGatewayRequestSchema; output: typeof CreateGatewayResponseSchema; - }; + }, /** * GetGateway * @@ -301,7 +288,7 @@ export const GatewayService: GenService<{ methodKind: "unary"; input: typeof GetGatewayRequestSchema; output: typeof GetGatewayResponseSchema; - }; + }, /** * DeleteGateway * @@ -311,5 +298,7 @@ export const GatewayService: GenService<{ methodKind: "unary"; input: typeof DeleteGatewayRequestSchema; output: typeof DeleteGatewayResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_krane_v1_gateway, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_krane_v1_gateway, 0); + diff --git a/apps/dashboard/gen/proto/vault/v1/object_pb.ts b/apps/dashboard/gen/proto/vault/v1/object_pb.ts index 93ba57ae33..4f9cf36bc0 100644 --- a/apps/dashboard/gen/proto/vault/v1/object_pb.ts +++ b/apps/dashboard/gen/proto/vault/v1/object_pb.ts @@ -2,18 +2,15 @@ // @generated from file vault/v1/object.proto (package vault.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file vault/v1/object.proto. */ -export const file_vault_v1_object: GenFile = - /*@__PURE__*/ - fileDesc( - "ChV2YXVsdC92MS9vYmplY3QucHJvdG8SCHZhdWx0LnYxIkAKEURhdGFFbmNyeXB0aW9uS2V5EgoKAmlkGAEgASgJEhIKCmNyZWF0ZWRfYXQYAiABKAMSCwoDa2V5GAMgASgMImQKGkVuY3J5cHRlZERhdGFFbmNyeXB0aW9uS2V5EgoKAmlkGAEgASgJEhIKCmNyZWF0ZWRfYXQYAiABKAMSJgoJZW5jcnlwdGVkGAMgASgLMhMudmF1bHQudjEuRW5jcnlwdGVkIj8KEEtleUVuY3J5cHRpb25LZXkSCgoCaWQYASABKAkSEgoKY3JlYXRlZF9hdBgCIAEoAxILCgNrZXkYAyABKAwifwoJRW5jcnlwdGVkEiYKCWFsZ29yaXRobRgBIAEoDjITLnZhdWx0LnYxLkFsZ29yaXRobRINCgVub25jZRgCIAEoDBISCgpjaXBoZXJ0ZXh0GAMgASgMEhkKEWVuY3J5cHRpb25fa2V5X2lkGAQgASgJEgwKBHRpbWUYBSABKAMqHAoJQWxnb3JpdGhtEg8KC0FFU18yNTZfR0NNEABClAEKDGNvbS52YXVsdC52MUILT2JqZWN0UHJvdG9QAVo2Z2l0aHViLmNvbS91bmtleWVkL3Vua2V5L2dvL2dlbi9wcm90by92YXVsdC92MTt2YXVsdHYxogIDVlhYqgIIVmF1bHQuVjHKAghWYXVsdFxWMeICFFZhdWx0XFYxXEdQQk1ldGFkYXRh6gIJVmF1bHQ6OlYxYgZwcm90bzM", - ); +export const file_vault_v1_object: GenFile = /*@__PURE__*/ + fileDesc("ChV2YXVsdC92MS9vYmplY3QucHJvdG8SCHZhdWx0LnYxIkAKEURhdGFFbmNyeXB0aW9uS2V5EgoKAmlkGAEgASgJEhIKCmNyZWF0ZWRfYXQYAiABKAMSCwoDa2V5GAMgASgMImQKGkVuY3J5cHRlZERhdGFFbmNyeXB0aW9uS2V5EgoKAmlkGAEgASgJEhIKCmNyZWF0ZWRfYXQYAiABKAMSJgoJZW5jcnlwdGVkGAMgASgLMhMudmF1bHQudjEuRW5jcnlwdGVkIj8KEEtleUVuY3J5cHRpb25LZXkSCgoCaWQYASABKAkSEgoKY3JlYXRlZF9hdBgCIAEoAxILCgNrZXkYAyABKAwifwoJRW5jcnlwdGVkEiYKCWFsZ29yaXRobRgBIAEoDjITLnZhdWx0LnYxLkFsZ29yaXRobRINCgVub25jZRgCIAEoDBISCgpjaXBoZXJ0ZXh0GAMgASgMEhkKEWVuY3J5cHRpb25fa2V5X2lkGAQgASgJEgwKBHRpbWUYBSABKAMqHAoJQWxnb3JpdGhtEg8KC0FFU18yNTZfR0NNEABClAEKDGNvbS52YXVsdC52MUILT2JqZWN0UHJvdG9QAVo2Z2l0aHViLmNvbS91bmtleWVkL3Vua2V5L2dvL2dlbi9wcm90by92YXVsdC92MTt2YXVsdHYxogIDVlhYqgIIVmF1bHQuVjHKAghWYXVsdFxWMeICFFZhdWx0XFYxXEdQQk1ldGFkYXRh6gIJVmF1bHQ6OlYxYgZwcm90bzM"); /** * @generated from message vault.v1.DataEncryptionKey @@ -41,8 +38,7 @@ export type DataEncryptionKey = Message<"vault.v1.DataEncryptionKey"> & { * Describes the message vault.v1.DataEncryptionKey. * Use `create(DataEncryptionKeySchema)` to create a new message. */ -export const DataEncryptionKeySchema: GenMessage = - /*@__PURE__*/ +export const DataEncryptionKeySchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_object, 0); /** @@ -73,8 +69,7 @@ export type EncryptedDataEncryptionKey = Message<"vault.v1.EncryptedDataEncrypti * Describes the message vault.v1.EncryptedDataEncryptionKey. * Use `create(EncryptedDataEncryptionKeySchema)` to create a new message. */ -export const EncryptedDataEncryptionKeySchema: GenMessage = - /*@__PURE__*/ +export const EncryptedDataEncryptionKeySchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_object, 1); /** @@ -103,8 +98,7 @@ export type KeyEncryptionKey = Message<"vault.v1.KeyEncryptionKey"> & { * Describes the message vault.v1.KeyEncryptionKey. * Use `create(KeyEncryptionKeySchema)` to create a new message. */ -export const KeyEncryptionKeySchema: GenMessage = - /*@__PURE__*/ +export const KeyEncryptionKeySchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_object, 2); /** @@ -148,8 +142,7 @@ export type Encrypted = Message<"vault.v1.Encrypted"> & { * Describes the message vault.v1.Encrypted. * Use `create(EncryptedSchema)` to create a new message. */ -export const EncryptedSchema: GenMessage = - /*@__PURE__*/ +export const EncryptedSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_object, 3); /** @@ -165,4 +158,6 @@ export enum Algorithm { /** * Describes the enum vault.v1.Algorithm. */ -export const AlgorithmSchema: GenEnum = /*@__PURE__*/ enumDesc(file_vault_v1_object, 0); +export const AlgorithmSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_vault_v1_object, 0); + diff --git a/apps/dashboard/gen/proto/vault/v1/service_pb.ts b/apps/dashboard/gen/proto/vault/v1/service_pb.ts index ad2e772cfe..f04bf7277a 100644 --- a/apps/dashboard/gen/proto/vault/v1/service_pb.ts +++ b/apps/dashboard/gen/proto/vault/v1/service_pb.ts @@ -2,30 +2,27 @@ // @generated from file vault/v1/service.proto (package vault.v1, syntax proto3) /* eslint-disable */ -import type { Message } from "@bufbuild/protobuf"; import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; /** * Describes the file vault/v1/service.proto. */ -export const file_vault_v1_service: GenFile = - /*@__PURE__*/ - fileDesc( - "ChZ2YXVsdC92MS9zZXJ2aWNlLnByb3RvEgh2YXVsdC52MSIRCg9MaXZlbmVzc1JlcXVlc3QiIgoQTGl2ZW5lc3NSZXNwb25zZRIOCgZzdGF0dXMYASABKAkiLwoORW5jcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIMCgRkYXRhGAIgASgJIjQKD0VuY3J5cHRSZXNwb25zZRIRCgllbmNyeXB0ZWQYASABKAkSDgoGa2V5X2lkGAIgASgJIjMKEkVuY3J5cHRCdWxrUmVxdWVzdBIPCgdrZXlyaW5nGAEgASgJEgwKBGRhdGEYAiADKAkiQwoTRW5jcnlwdEJ1bGtSZXNwb25zZRIsCgllbmNyeXB0ZWQYASADKAsyGS52YXVsdC52MS5FbmNyeXB0UmVzcG9uc2UiNAoORGVjcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIRCgllbmNyeXB0ZWQYAiABKAkiJAoPRGVjcnlwdFJlc3BvbnNlEhEKCXBsYWludGV4dBgBIAEoCSIjChBDcmVhdGVERUtSZXF1ZXN0Eg8KB2tleXJpbmcYASABKAkiIwoRQ3JlYXRlREVLUmVzcG9uc2USDgoGa2V5X2lkGAEgASgJIlYKEFJlRW5jcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIRCgllbmNyeXB0ZWQYAiABKAkSEwoGa2V5X2lkGAMgASgJSACIAQFCCQoHX2tleV9pZCI2ChFSZUVuY3J5cHRSZXNwb25zZRIRCgllbmNyeXB0ZWQYASABKAkSDgoGa2V5X2lkGAIgASgJIhYKFFJlRW5jcnlwdERFS3NSZXF1ZXN0IhcKFVJlRW5jcnlwdERFS3NSZXNwb25zZTKJBAoMVmF1bHRTZXJ2aWNlEkMKCExpdmVuZXNzEhkudmF1bHQudjEuTGl2ZW5lc3NSZXF1ZXN0GhoudmF1bHQudjEuTGl2ZW5lc3NSZXNwb25zZSIAEkYKCUNyZWF0ZURFSxIaLnZhdWx0LnYxLkNyZWF0ZURFS1JlcXVlc3QaGy52YXVsdC52MS5DcmVhdGVERUtSZXNwb25zZSIAEkAKB0VuY3J5cHQSGC52YXVsdC52MS5FbmNyeXB0UmVxdWVzdBoZLnZhdWx0LnYxLkVuY3J5cHRSZXNwb25zZSIAEkwKC0VuY3J5cHRCdWxrEhwudmF1bHQudjEuRW5jcnlwdEJ1bGtSZXF1ZXN0Gh0udmF1bHQudjEuRW5jcnlwdEJ1bGtSZXNwb25zZSIAEkAKB0RlY3J5cHQSGC52YXVsdC52MS5EZWNyeXB0UmVxdWVzdBoZLnZhdWx0LnYxLkRlY3J5cHRSZXNwb25zZSIAEkYKCVJlRW5jcnlwdBIaLnZhdWx0LnYxLlJlRW5jcnlwdFJlcXVlc3QaGy52YXVsdC52MS5SZUVuY3J5cHRSZXNwb25zZSIAElIKDVJlRW5jcnlwdERFS3MSHi52YXVsdC52MS5SZUVuY3J5cHRERUtzUmVxdWVzdBofLnZhdWx0LnYxLlJlRW5jcnlwdERFS3NSZXNwb25zZSIAQpUBCgxjb20udmF1bHQudjFCDFNlcnZpY2VQcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL3ZhdWx0L3YxO3ZhdWx0djGiAgNWWFiqAghWYXVsdC5WMcoCCFZhdWx0XFYx4gIUVmF1bHRcVjFcR1BCTWV0YWRhdGHqAglWYXVsdDo6VjFiBnByb3RvMw", - ); +export const file_vault_v1_service: GenFile = /*@__PURE__*/ + fileDesc("ChZ2YXVsdC92MS9zZXJ2aWNlLnByb3RvEgh2YXVsdC52MSIRCg9MaXZlbmVzc1JlcXVlc3QiIgoQTGl2ZW5lc3NSZXNwb25zZRIOCgZzdGF0dXMYASABKAkiLwoORW5jcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIMCgRkYXRhGAIgASgJIjQKD0VuY3J5cHRSZXNwb25zZRIRCgllbmNyeXB0ZWQYASABKAkSDgoGa2V5X2lkGAIgASgJIjMKEkVuY3J5cHRCdWxrUmVxdWVzdBIPCgdrZXlyaW5nGAEgASgJEgwKBGRhdGEYAiADKAkiQwoTRW5jcnlwdEJ1bGtSZXNwb25zZRIsCgllbmNyeXB0ZWQYASADKAsyGS52YXVsdC52MS5FbmNyeXB0UmVzcG9uc2UiNAoORGVjcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIRCgllbmNyeXB0ZWQYAiABKAkiJAoPRGVjcnlwdFJlc3BvbnNlEhEKCXBsYWludGV4dBgBIAEoCSIjChBDcmVhdGVERUtSZXF1ZXN0Eg8KB2tleXJpbmcYASABKAkiIwoRQ3JlYXRlREVLUmVzcG9uc2USDgoGa2V5X2lkGAEgASgJIlYKEFJlRW5jcnlwdFJlcXVlc3QSDwoHa2V5cmluZxgBIAEoCRIRCgllbmNyeXB0ZWQYAiABKAkSEwoGa2V5X2lkGAMgASgJSACIAQFCCQoHX2tleV9pZCI2ChFSZUVuY3J5cHRSZXNwb25zZRIRCgllbmNyeXB0ZWQYASABKAkSDgoGa2V5X2lkGAIgASgJIhYKFFJlRW5jcnlwdERFS3NSZXF1ZXN0IhcKFVJlRW5jcnlwdERFS3NSZXNwb25zZTKJBAoMVmF1bHRTZXJ2aWNlEkMKCExpdmVuZXNzEhkudmF1bHQudjEuTGl2ZW5lc3NSZXF1ZXN0GhoudmF1bHQudjEuTGl2ZW5lc3NSZXNwb25zZSIAEkYKCUNyZWF0ZURFSxIaLnZhdWx0LnYxLkNyZWF0ZURFS1JlcXVlc3QaGy52YXVsdC52MS5DcmVhdGVERUtSZXNwb25zZSIAEkAKB0VuY3J5cHQSGC52YXVsdC52MS5FbmNyeXB0UmVxdWVzdBoZLnZhdWx0LnYxLkVuY3J5cHRSZXNwb25zZSIAEkwKC0VuY3J5cHRCdWxrEhwudmF1bHQudjEuRW5jcnlwdEJ1bGtSZXF1ZXN0Gh0udmF1bHQudjEuRW5jcnlwdEJ1bGtSZXNwb25zZSIAEkAKB0RlY3J5cHQSGC52YXVsdC52MS5EZWNyeXB0UmVxdWVzdBoZLnZhdWx0LnYxLkRlY3J5cHRSZXNwb25zZSIAEkYKCVJlRW5jcnlwdBIaLnZhdWx0LnYxLlJlRW5jcnlwdFJlcXVlc3QaGy52YXVsdC52MS5SZUVuY3J5cHRSZXNwb25zZSIAElIKDVJlRW5jcnlwdERFS3MSHi52YXVsdC52MS5SZUVuY3J5cHRERUtzUmVxdWVzdBofLnZhdWx0LnYxLlJlRW5jcnlwdERFS3NSZXNwb25zZSIAQpUBCgxjb20udmF1bHQudjFCDFNlcnZpY2VQcm90b1ABWjZnaXRodWIuY29tL3Vua2V5ZWQvdW5rZXkvZ28vZ2VuL3Byb3RvL3ZhdWx0L3YxO3ZhdWx0djGiAgNWWFiqAghWYXVsdC5WMcoCCFZhdWx0XFYx4gIUVmF1bHRcVjFcR1BCTWV0YWRhdGHqAglWYXVsdDo6VjFiBnByb3RvMw"); /** * @generated from message vault.v1.LivenessRequest */ -export type LivenessRequest = Message<"vault.v1.LivenessRequest"> & {}; +export type LivenessRequest = Message<"vault.v1.LivenessRequest"> & { +}; /** * Describes the message vault.v1.LivenessRequest. * Use `create(LivenessRequestSchema)` to create a new message. */ -export const LivenessRequestSchema: GenMessage = - /*@__PURE__*/ +export const LivenessRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 0); /** @@ -42,8 +39,7 @@ export type LivenessResponse = Message<"vault.v1.LivenessResponse"> & { * Describes the message vault.v1.LivenessResponse. * Use `create(LivenessResponseSchema)` to create a new message. */ -export const LivenessResponseSchema: GenMessage = - /*@__PURE__*/ +export const LivenessResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 1); /** @@ -65,8 +61,7 @@ export type EncryptRequest = Message<"vault.v1.EncryptRequest"> & { * Describes the message vault.v1.EncryptRequest. * Use `create(EncryptRequestSchema)` to create a new message. */ -export const EncryptRequestSchema: GenMessage = - /*@__PURE__*/ +export const EncryptRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 2); /** @@ -88,8 +83,7 @@ export type EncryptResponse = Message<"vault.v1.EncryptResponse"> & { * Describes the message vault.v1.EncryptResponse. * Use `create(EncryptResponseSchema)` to create a new message. */ -export const EncryptResponseSchema: GenMessage = - /*@__PURE__*/ +export const EncryptResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 3); /** @@ -111,8 +105,7 @@ export type EncryptBulkRequest = Message<"vault.v1.EncryptBulkRequest"> & { * Describes the message vault.v1.EncryptBulkRequest. * Use `create(EncryptBulkRequestSchema)` to create a new message. */ -export const EncryptBulkRequestSchema: GenMessage = - /*@__PURE__*/ +export const EncryptBulkRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 4); /** @@ -129,8 +122,7 @@ export type EncryptBulkResponse = Message<"vault.v1.EncryptBulkResponse"> & { * Describes the message vault.v1.EncryptBulkResponse. * Use `create(EncryptBulkResponseSchema)` to create a new message. */ -export const EncryptBulkResponseSchema: GenMessage = - /*@__PURE__*/ +export const EncryptBulkResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 5); /** @@ -152,8 +144,7 @@ export type DecryptRequest = Message<"vault.v1.DecryptRequest"> & { * Describes the message vault.v1.DecryptRequest. * Use `create(DecryptRequestSchema)` to create a new message. */ -export const DecryptRequestSchema: GenMessage = - /*@__PURE__*/ +export const DecryptRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 6); /** @@ -170,8 +161,7 @@ export type DecryptResponse = Message<"vault.v1.DecryptResponse"> & { * Describes the message vault.v1.DecryptResponse. * Use `create(DecryptResponseSchema)` to create a new message. */ -export const DecryptResponseSchema: GenMessage = - /*@__PURE__*/ +export const DecryptResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 7); /** @@ -188,8 +178,7 @@ export type CreateDEKRequest = Message<"vault.v1.CreateDEKRequest"> & { * Describes the message vault.v1.CreateDEKRequest. * Use `create(CreateDEKRequestSchema)` to create a new message. */ -export const CreateDEKRequestSchema: GenMessage = - /*@__PURE__*/ +export const CreateDEKRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 8); /** @@ -206,8 +195,7 @@ export type CreateDEKResponse = Message<"vault.v1.CreateDEKResponse"> & { * Describes the message vault.v1.CreateDEKResponse. * Use `create(CreateDEKResponseSchema)` to create a new message. */ -export const CreateDEKResponseSchema: GenMessage = - /*@__PURE__*/ +export const CreateDEKResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 9); /** @@ -236,8 +224,7 @@ export type ReEncryptRequest = Message<"vault.v1.ReEncryptRequest"> & { * Describes the message vault.v1.ReEncryptRequest. * Use `create(ReEncryptRequestSchema)` to create a new message. */ -export const ReEncryptRequestSchema: GenMessage = - /*@__PURE__*/ +export const ReEncryptRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 10); /** @@ -259,34 +246,33 @@ export type ReEncryptResponse = Message<"vault.v1.ReEncryptResponse"> & { * Describes the message vault.v1.ReEncryptResponse. * Use `create(ReEncryptResponseSchema)` to create a new message. */ -export const ReEncryptResponseSchema: GenMessage = - /*@__PURE__*/ +export const ReEncryptResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 11); /** * @generated from message vault.v1.ReEncryptDEKsRequest */ -export type ReEncryptDEKsRequest = Message<"vault.v1.ReEncryptDEKsRequest"> & {}; +export type ReEncryptDEKsRequest = Message<"vault.v1.ReEncryptDEKsRequest"> & { +}; /** * Describes the message vault.v1.ReEncryptDEKsRequest. * Use `create(ReEncryptDEKsRequestSchema)` to create a new message. */ -export const ReEncryptDEKsRequestSchema: GenMessage = - /*@__PURE__*/ +export const ReEncryptDEKsRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 12); /** * @generated from message vault.v1.ReEncryptDEKsResponse */ -export type ReEncryptDEKsResponse = Message<"vault.v1.ReEncryptDEKsResponse"> & {}; +export type ReEncryptDEKsResponse = Message<"vault.v1.ReEncryptDEKsResponse"> & { +}; /** * Describes the message vault.v1.ReEncryptDEKsResponse. * Use `create(ReEncryptDEKsResponseSchema)` to create a new message. */ -export const ReEncryptDEKsResponseSchema: GenMessage = - /*@__PURE__*/ +export const ReEncryptDEKsResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_vault_v1_service, 13); /** @@ -300,7 +286,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof LivenessRequestSchema; output: typeof LivenessResponseSchema; - }; + }, /** * @generated from rpc vault.v1.VaultService.CreateDEK */ @@ -308,7 +294,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof CreateDEKRequestSchema; output: typeof CreateDEKResponseSchema; - }; + }, /** * @generated from rpc vault.v1.VaultService.Encrypt */ @@ -316,7 +302,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof EncryptRequestSchema; output: typeof EncryptResponseSchema; - }; + }, /** * @generated from rpc vault.v1.VaultService.EncryptBulk */ @@ -324,7 +310,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof EncryptBulkRequestSchema; output: typeof EncryptBulkResponseSchema; - }; + }, /** * @generated from rpc vault.v1.VaultService.Decrypt */ @@ -332,7 +318,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof DecryptRequestSchema; output: typeof DecryptResponseSchema; - }; + }, /** * ReEncrypt rec * @@ -342,7 +328,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof ReEncryptRequestSchema; output: typeof ReEncryptResponseSchema; - }; + }, /** * @generated from rpc vault.v1.VaultService.ReEncryptDEKs */ @@ -350,5 +336,7 @@ export const VaultService: GenService<{ methodKind: "unary"; input: typeof ReEncryptDEKsRequestSchema; output: typeof ReEncryptDEKsResponseSchema; - }; -}> = /*@__PURE__*/ serviceDesc(file_vault_v1_service, 0); + }, +}> = /*@__PURE__*/ + serviceDesc(file_vault_v1_service, 0); + diff --git a/apps/dashboard/lib/trpc/routers/deploy/env-vars/create.ts b/apps/dashboard/lib/trpc/routers/deploy/env-vars/create.ts new file mode 100644 index 0000000000..c279873326 --- /dev/null +++ b/apps/dashboard/lib/trpc/routers/deploy/env-vars/create.ts @@ -0,0 +1,85 @@ +import { and, db, eq, schema } from "@/lib/db"; +import { env } from "@/lib/env"; +import { Vault } from "@/lib/vault"; +import { TRPCError } from "@trpc/server"; +import { environments } from "@unkey/db/src/schema"; +import { newId } from "@unkey/id"; +import { z } from "zod"; +import { requireUser, requireWorkspace, t } from "../../../trpc"; + +const vault = new Vault({ + baseUrl: env().AGENT_URL, + token: env().AGENT_TOKEN, +}); + +const envVarInputSchema = z.object({ + key: z.string().min(1), + value: z.string().min(1), + type: z.enum(["recoverable", "writeonly"]), + description: z.string().nullable().optional(), +}); + +export const createEnvVars = t.procedure + .use(requireUser) + .use(requireWorkspace) + .input( + z.object({ + environmentId: z.string(), + variables: z.array(envVarInputSchema).min(1), + }), + ) + .mutation(async ({ ctx, input }) => { + // Verify the environment belongs to this workspace + const environment = await db.query.environments.findFirst({ + where: and( + eq(environments.id, input.environmentId), + eq(environments.workspaceId, ctx.workspace.id), + ), + columns: { + id: true, + }, + }); + + if (!environment) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Environment not found", + }); + } + + try { + // Encrypt all values + const encryptedVars = await Promise.all( + input.variables.map(async (v) => { + const { encrypted } = await vault.encrypt({ + keyring: ctx.workspace.id, + data: v.value, + }); + + return { + id: newId("environmentVariable"), + workspaceId: ctx.workspace.id, + environmentId: input.environmentId, + key: v.key, + value: encrypted, + type: v.type, + description: v.description ?? null, + }; + }), + ); + + // Insert all in one query + await db.insert(schema.environmentVariables).values(encryptedVars); + + return { + count: encryptedVars.length, + ids: encryptedVars.map((v) => v.id), + }; + } catch (error) { + console.error("Failed to create environment variables:", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to create environment variables", + }); + } + }); diff --git a/apps/dashboard/lib/trpc/routers/deploy/env-vars/decrypt.ts b/apps/dashboard/lib/trpc/routers/deploy/env-vars/decrypt.ts new file mode 100644 index 0000000000..08ad3a2927 --- /dev/null +++ b/apps/dashboard/lib/trpc/routers/deploy/env-vars/decrypt.ts @@ -0,0 +1,70 @@ +import { and, db, eq } from "@/lib/db"; +import { env } from "@/lib/env"; +import { Vault } from "@/lib/vault"; +import { TRPCError } from "@trpc/server"; +import { environmentVariables } from "@unkey/db/src/schema"; +import { z } from "zod"; +import { requireUser, requireWorkspace, t } from "../../../trpc"; + +const vault = new Vault({ + baseUrl: env().AGENT_URL, + token: env().AGENT_TOKEN, +}); + +export const decryptEnvVar = t.procedure + .use(requireUser) + .use(requireWorkspace) + .input( + z.object({ + envVarId: z.string(), + }), + ) + .output( + z.object({ + value: z.string(), + }), + ) + .mutation(async ({ ctx, input }) => { + // Fetch the environment variable + const envVar = await db.query.environmentVariables.findFirst({ + where: and( + eq(environmentVariables.id, input.envVarId), + eq(environmentVariables.workspaceId, ctx.workspace.id), + ), + columns: { + id: true, + value: true, + type: true, + }, + }); + + if (!envVar) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Environment variable not found", + }); + } + + // Only recoverable vars can be decrypted + if (envVar.type === "writeonly") { + throw new TRPCError({ + code: "FORBIDDEN", + message: "Writeonly environment variables cannot be decrypted", + }); + } + + try { + const { plaintext } = await vault.decrypt({ + keyring: ctx.workspace.id, + encrypted: envVar.value, + }); + + return { value: plaintext }; + } catch (error) { + console.error("Failed to decrypt environment variable:", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to decrypt environment variable", + }); + } + }); diff --git a/apps/dashboard/lib/trpc/routers/deploy/env-vars/delete.ts b/apps/dashboard/lib/trpc/routers/deploy/env-vars/delete.ts new file mode 100644 index 0000000000..d721acd4a8 --- /dev/null +++ b/apps/dashboard/lib/trpc/routers/deploy/env-vars/delete.ts @@ -0,0 +1,38 @@ +import { and, db, eq, schema } from "@/lib/db"; +import { TRPCError } from "@trpc/server"; +import { z } from "zod"; +import { requireUser, requireWorkspace, t } from "../../../trpc"; + +export const deleteEnvVar = t.procedure + .use(requireUser) + .use(requireWorkspace) + .input( + z.object({ + envVarId: z.string(), + }), + ) + .mutation(async ({ ctx, input }) => { + // Verify the env var belongs to this workspace + const envVar = await db.query.environmentVariables.findFirst({ + where: and( + eq(schema.environmentVariables.id, input.envVarId), + eq(schema.environmentVariables.workspaceId, ctx.workspace.id), + ), + columns: { + id: true, + }, + }); + + if (!envVar) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Environment variable not found", + }); + } + + await db + .delete(schema.environmentVariables) + .where(eq(schema.environmentVariables.id, input.envVarId)); + + return { success: true }; + }); diff --git a/apps/dashboard/lib/trpc/routers/deploy/env-vars/list.ts b/apps/dashboard/lib/trpc/routers/deploy/env-vars/list.ts new file mode 100644 index 0000000000..fdf3588ae0 --- /dev/null +++ b/apps/dashboard/lib/trpc/routers/deploy/env-vars/list.ts @@ -0,0 +1,94 @@ +import { and, db, eq, inArray } from "@/lib/db"; +import { TRPCError } from "@trpc/server"; +import { environmentVariables, environments } from "@unkey/db/src/schema"; +import { z } from "zod"; +import { requireUser, requireWorkspace, t } from "../../../trpc"; + +const envVarOutputSchema = z.object({ + id: z.string(), + key: z.string(), + value: z.string(), + type: z.enum(["recoverable", "writeonly"]), + description: z.string().nullable(), +}); + +const environmentOutputSchema = z.object({ + id: z.string(), + variables: z.array(envVarOutputSchema), +}); + +export const listEnvVars = t.procedure + .use(requireUser) + .use(requireWorkspace) + .input( + z.object({ + projectId: z.string(), + }), + ) + .query(async ({ ctx, input }) => { + try { + // Fetch all environments for this project + const envs = await db.query.environments.findMany({ + where: and( + eq(environments.workspaceId, ctx.workspace.id), + eq(environments.projectId, input.projectId), + ), + columns: { + id: true, + slug: true, + }, + }); + + const envIds = envs.map((e) => e.id); + + if (envIds.length === 0) { + return {}; + } + + // Fetch all environment variables in one query + const allVariables = await db.query.environmentVariables.findMany({ + where: and( + eq(environmentVariables.workspaceId, ctx.workspace.id), + inArray(environmentVariables.environmentId, envIds), + ), + columns: { + id: true, + environmentId: true, + key: true, + value: true, + type: true, + description: true, + }, + }); + + // Group by environment slug + const result: Record> = {}; + + for (const env of envs) { + const vars = allVariables.filter((v) => v.environmentId === env.id); + + result[env.slug] = { + id: env.id, + variables: vars.map((v) => ({ + id: v.id, + key: v.key, + // Always masked - use decrypt endpoint to reveal + value: "••••••••", + type: v.type, + description: v.description, + })), + }; + } + + return result; + } catch (error) { + if (error instanceof TRPCError) { + throw error; + } + console.error("Failed to fetch environment variables:", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to fetch environment variables", + }); + } + }); diff --git a/apps/dashboard/lib/trpc/routers/deploy/env-vars/update.ts b/apps/dashboard/lib/trpc/routers/deploy/env-vars/update.ts new file mode 100644 index 0000000000..9a828cd36c --- /dev/null +++ b/apps/dashboard/lib/trpc/routers/deploy/env-vars/update.ts @@ -0,0 +1,79 @@ +import { and, db, eq, schema } from "@/lib/db"; +import { env } from "@/lib/env"; +import { Vault } from "@/lib/vault"; +import { TRPCError } from "@trpc/server"; +import { z } from "zod"; +import { requireUser, requireWorkspace, t } from "../../../trpc"; + +const vault = new Vault({ + baseUrl: env().AGENT_URL, + token: env().AGENT_TOKEN, +}); + +export const updateEnvVar = t.procedure + .use(requireUser) + .use(requireWorkspace) + .input( + z.object({ + envVarId: z.string(), + // Key can only be updated for recoverable vars (validated on client) + key: z.string().min(1).optional(), + // Value is always re-encrypted + value: z.string().min(1), + type: z.enum(["recoverable", "writeonly"]), + }), + ) + .mutation(async ({ ctx, input }) => { + // Verify the env var belongs to this workspace + const envVar = await db.query.environmentVariables.findFirst({ + where: and( + eq(schema.environmentVariables.id, input.envVarId), + eq(schema.environmentVariables.workspaceId, ctx.workspace.id), + ), + columns: { + id: true, + type: true, + key: true, + }, + }); + + if (!envVar) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Environment variable not found", + }); + } + + // Writeonly vars cannot have their key renamed + if (envVar.type === "writeonly" && input.key && input.key !== envVar.key) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "Cannot rename writeonly environment variables", + }); + } + + // Type cannot be changed after creation + if (input.type !== envVar.type) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "Cannot change environment variable type after creation", + }); + } + + // Encrypt the new value + const { encrypted } = await vault.encrypt({ + keyring: ctx.workspace.id, + data: input.value, + }); + + await db + .update(schema.environmentVariables) + .set({ + key: input.key ?? envVar.key, + value: encrypted, + type: input.type, + }) + .where(eq(schema.environmentVariables.id, input.envVarId)); + + return { success: true }; + }); diff --git a/apps/dashboard/lib/trpc/routers/deploy/envs/list.ts b/apps/dashboard/lib/trpc/routers/deploy/envs/list.ts deleted file mode 100644 index 4d1438e920..0000000000 --- a/apps/dashboard/lib/trpc/routers/deploy/envs/list.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { envVarSchema } from "@/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/types"; -import { ratelimit, requireUser, requireWorkspace, t, withRatelimit } from "@/lib/trpc/trpc"; -import { z } from "zod"; - -const environmentVariablesOutputSchema = z.object({ - production: z.array(envVarSchema), - preview: z.array(envVarSchema), -}); - -export type EnvironmentVariables = z.infer; -export type EnvVar = z.infer; - -export const VARIABLES: EnvironmentVariables = { - production: [ - { - id: "1", - key: "DATABASE_URL", - value: "postgresql://user:pass@prod.db.com:5432/app", - type: "secret", - }, - { - id: "2", - key: "API_KEY", - value: "sk_prod_1234567890abcdef", - type: "secret", - }, - { - id: "3", - key: "NODE_ENV", - value: "production", - type: "env", - }, - { - id: "4", - key: "REDIS_URL", - value: "redis://prod.redis.com:6379", - type: "secret", - }, - { - id: "5", - key: "LOG_LEVEL", - value: "info", - type: "env", - }, - ], - preview: [ - { - id: "6", - key: "DATABASE_URL", - value: "postgresql://user:pass@staging.db.com:5432/app", - type: "secret", - }, - { - id: "7", - key: "API_KEY", - value: "sk_test_abcdef1234567890", - type: "secret", - }, - { - id: "8", - key: "NODE_ENV", - value: "development", - type: "env", - }, - ], -}; - -export const getEnvs = t.procedure - .use(requireUser) - .use(requireWorkspace) - .use(withRatelimit(ratelimit.read)) - .input( - z.object({ - projectId: z.string(), - }), - ) - .output(environmentVariablesOutputSchema) - .query(() => { - return VARIABLES; - }); diff --git a/apps/dashboard/lib/trpc/routers/index.ts b/apps/dashboard/lib/trpc/routers/index.ts index 9790a43ad8..addce811e4 100644 --- a/apps/dashboard/lib/trpc/routers/index.ts +++ b/apps/dashboard/lib/trpc/routers/index.ts @@ -45,7 +45,11 @@ import { searchDeployments } from "./deploy/deployment/llm-search"; import { promote } from "./deploy/deployment/promote"; import { rollback } from "./deploy/deployment/rollback"; import { listDomains } from "./deploy/domains/list"; -import { getEnvs } from "./deploy/envs/list"; +import { createEnvVars } from "./deploy/env-vars/create"; +import { decryptEnvVar } from "./deploy/env-vars/decrypt"; +import { deleteEnvVar } from "./deploy/env-vars/delete"; +import { listEnvVars } from "./deploy/env-vars/list"; +import { updateEnvVar } from "./deploy/env-vars/update"; import { generateDeploymentTree } from "./deploy/network/generate"; import { getDeploymentTree } from "./deploy/network/get"; import { createProject } from "./deploy/project/create"; @@ -349,9 +353,15 @@ export const router = t.router({ create: createProject, }), environment: t.router({ - list_dummy: getEnvs, list: listEnvironments, }), + envVar: t.router({ + list: listEnvVars, + create: createEnvVars, + update: updateEnvVar, + decrypt: decryptEnvVar, + delete: deleteEnvVar, + }), domain: t.router({ list: listDomains, }), diff --git a/apps/docs/docs.json b/apps/docs/docs.json index 35171402f2..b5b83f0b87 100644 --- a/apps/docs/docs.json +++ b/apps/docs/docs.json @@ -73,7 +73,9 @@ }, { "group": "Identities", - "pages": ["quickstart/identities/shared-ratelimits"] + "pages": [ + "quickstart/identities/shared-ratelimits" + ] } ] }, @@ -107,7 +109,10 @@ { "group": "Identities", "icon": "fingerprint", - "pages": ["concepts/identities/overview", "concepts/identities/ratelimits"] + "pages": [ + "concepts/identities/overview", + "concepts/identities/ratelimits" + ] } ] }, @@ -124,7 +129,9 @@ "pages": [ { "group": "Ratelimiting", - "pages": ["apis/features/ratelimiting/overview"] + "pages": [ + "apis/features/ratelimiting/overview" + ] }, "apis/features/temp-keys", "apis/features/remaining", @@ -160,7 +167,10 @@ { "group": "Audit logs", "icon": "scroll", - "pages": ["audit-log/introduction", "audit-log/types"] + "pages": [ + "audit-log/introduction", + "audit-log/types" + ] }, { "group": "Analytics", @@ -184,7 +194,10 @@ { "group": "Migrating API Keys", "icon": "plane", - "pages": ["migrations/introduction", "migrations/keys"] + "pages": [ + "migrations/introduction", + "migrations/keys" + ] } ] }, @@ -270,7 +283,9 @@ }, { "group": "Too Many Requests", - "pages": ["errors/user/too_many_requests/query_quota_exceeded"] + "pages": [ + "errors/user/too_many_requests/query_quota_exceeded" + ] }, { "group": "Unprocessable Entity", @@ -377,11 +392,15 @@ }, { "group": "Go", - "pages": ["libraries/go/api"] + "pages": [ + "libraries/go/api" + ] }, { "group": "Python", - "pages": ["libraries/py/api"] + "pages": [ + "libraries/py/api" + ] } ] }, @@ -406,11 +425,15 @@ }, { "group": "Nuxt", - "pages": ["libraries/nuxt/overview"] + "pages": [ + "libraries/nuxt/overview" + ] }, { "group": "Rust", - "pages": ["libraries/rs/overview"] + "pages": [ + "libraries/rs/overview" + ] }, { "group": "Springboot", @@ -457,4 +480,4 @@ "codeblocks": "system" }, "theme": "maple" -} +} \ No newline at end of file diff --git a/biome.json b/biome.json index 1bf5bbd4bf..0d861e125b 100644 --- a/biome.json +++ b/biome.json @@ -74,9 +74,10 @@ ".next", "dist", ".nuxt", + "./apps/docs/docs.json", "./packages/api/src/openapi.d.ts", "./internal/auth-migrator/", - "./internal/proto/generated/**/*.ts", + "./apps/dashboard/gen/proto/**/*.ts", ".wrangler", ".react-email", ".content-collections", @@ -100,7 +101,9 @@ ".source", ".trigger", "./internal/auth-migrator", - "./internal/proto/generated/**/*.ts" + "./internal/proto/generated/**/*.ts", + "./apps/dashboard/gen/proto/**/*.ts", + "./apps/docs/docs.json" ] }, "organizeImports": { @@ -114,7 +117,9 @@ ".react-email", ".content-collections", "./internal/auth-migrator", - "./internal/proto/generated/**/*.ts" + "./internal/proto/generated/**/*.ts", + "./apps/dashboard/gen/proto/**/*.ts", + "./apps/docs/docs.json" ] }, "overrides": [ diff --git a/internal/id/src/generate.ts b/internal/id/src/generate.ts index 7b6e1e3c2b..d24a8b442d 100644 --- a/internal/id/src/generate.ts +++ b/internal/id/src/generate.ts @@ -29,6 +29,7 @@ const prefixes = { auditLog: "log", fake: "fake", environment: "env", + environmentVariable: "evr", project: "proj", } as const; From 117e0d4abad74ee689cd2606daf32a4b8f2e0804 Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 14:56:46 +0100 Subject: [PATCH 06/18] fix comment and rename file --- .../env-variables-section/add-env-var-row.tsx | 115 ------------------ ...bulk-add-env-vars.tsx => add-env-vars.tsx} | 0 .../components/env-var-inputs.tsx | 1 + 3 files changed, 1 insertion(+), 115 deletions(-) delete mode 100644 apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx rename apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/{bulk-add-env-vars.tsx => add-env-vars.tsx} (100%) diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx deleted file mode 100644 index f737a6640e..0000000000 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { trpc } from "@/lib/trpc/client"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm } from "react-hook-form"; -import { EnvVarInputs } from "./components/env-var-inputs"; -import { EnvVarSaveActions } from "./components/env-var-save-actions"; -import { EnvVarSecretSwitch } from "./components/env-var-secret-switch"; -import { type EnvVar, type EnvVarFormData, EnvVarFormSchema } from "./types"; - -type AddEnvVarRowProps = { - environmentId: string; - getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; - onCancel: () => void; - onSuccess: () => void; -}; - -export function AddEnvVarRow({ - environmentId, - getExistingEnvVar, - onCancel, - onSuccess, -}: AddEnvVarRowProps) { - const createMutation = trpc.deploy.envVar.create.useMutation(); - - const { - register, - handleSubmit, - watch, - setValue, - formState: { errors, isValid }, - } = useForm({ - resolver: zodResolver( - EnvVarFormSchema.superRefine((data, ctx) => { - const existing = getExistingEnvVar(data.key); - if (existing) { - ctx.addIssue({ - code: "custom", - message: "Variable name already exists", - path: ["key"], - }); - } - }), - ), - defaultValues: { - key: "", - value: "", - type: "recoverable", - }, - }); - - const watchedType = watch("type"); - const isSubmitting = createMutation.isLoading; - - const handleSave = async (formData: EnvVarFormData) => { - try { - await createMutation.mutateAsync({ - environmentId, - variables: [ - { - key: formData.key, - value: formData.value, - type: formData.type, - }, - ], - }); - onSuccess(); - } catch (error) { - console.error("Failed to add env var:", error); - } - }; - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && isValid && !isSubmitting) { - handleSubmit(handleSave)(); - } else if (e.key === "Escape") { - onCancel(); - } - }; - - return ( -
- - -
- - setValue("type", checked ? "writeonly" : "recoverable", { - shouldDirty: true, - shouldValidate: true, - }) - } - disabled={isSubmitting} - /> - -
- -
- ); -} diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx similarity index 100% rename from apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/bulk-add-env-vars.tsx rename to apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-inputs.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-inputs.tsx index 5a3b273eca..76f4e48edf 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-inputs.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/components/env-var-inputs.tsx @@ -28,6 +28,7 @@ export const EnvVarInputs = forwardRef( return; } // Auto-uppercase the key and replace spaces with underscores + // nothing else should be valid in an env var... setValue("key", e.target.value.toUpperCase().replace(/ /g, "_"), { shouldValidate: true, }); From 8cd90b5031526cab51d00576533d7d3907d9707f Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 2 Dec 2025 15:05:02 +0100 Subject: [PATCH 07/18] fix file export name --- .../env-variables-section/add-env-vars.tsx | 64 ++++++++++--------- .../details/env-variables-section/index.tsx | 4 +- .../details/env-variables-section/types.ts | 6 +- .../trpc/routers/deploy/env-vars/delete.ts | 26 +++----- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx index 90de2126d3..6896a9c3ae 100644 --- a/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx +++ b/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/details/env-variables-section/add-env-vars.tsx @@ -1,10 +1,10 @@ import { trpc } from "@/lib/trpc/client"; import { cn } from "@/lib/utils"; import { Plus, Trash } from "@unkey/icons"; -import { Button } from "@unkey/ui"; +import { Button, Input } from "@unkey/ui"; import { useEffect, useRef, useState } from "react"; import { EnvVarSecretSwitch } from "./components/env-var-secret-switch"; -import type { EnvVar, EnvVarType } from "./types"; +import { ENV_VAR_KEY_REGEX, type EnvVar, type EnvVarType } from "./types"; type EnvVarEntry = { id: string; @@ -13,7 +13,7 @@ type EnvVarEntry = { type: EnvVarType; }; -type BulkAddEnvVarsProps = { +type AddEnvVarsProps = { environmentId: string; getExistingEnvVar: (key: string, excludeId?: string) => EnvVar | undefined; onCancel: () => void; @@ -74,7 +74,7 @@ function parseEnvFile(content: string): EnvVarEntry[] { const value = cleanEnvValue(trimmed.slice(eqIndex + 1)); const upperKey = key.toUpperCase(); - if (upperKey && /^[A-Z][A-Z0-9_]*$/.test(upperKey)) { + if (upperKey && ENV_VAR_KEY_REGEX.test(upperKey)) { entries.push({ id: crypto.randomUUID(), key: upperKey, @@ -87,12 +87,12 @@ function parseEnvFile(content: string): EnvVarEntry[] { return entries; } -export function BulkAddEnvVars({ +export function AddEnvVars({ environmentId, getExistingEnvVar, onCancel, onSuccess, -}: BulkAddEnvVarsProps) { +}: AddEnvVarsProps) { const createMutation = trpc.deploy.envVar.create.useMutation(); const containerRef = useRef(null); const [entries, setEntries] = useState([ @@ -112,7 +112,7 @@ export function BulkAddEnvVars({ // Focus the new entry's key input after render setTimeout(() => { const inputs = containerRef.current?.querySelectorAll( - 'input[placeholder="KEY"]', + 'input[placeholder="KEY_NAME"]', ); inputs?.[inputs.length - 1]?.focus(); }, 0); @@ -131,7 +131,7 @@ export function BulkAddEnvVars({ // Move focus to value field const valueInput = (e.target as HTMLInputElement) .closest(".flex") - ?.querySelector('input[placeholder="value"]'); + ?.querySelector('input[placeholder="Variable value"]'); valueInput?.focus(); } else if (field === "value" && !isLastEntry) { // Move focus to next row's key field @@ -139,7 +139,7 @@ export function BulkAddEnvVars({ ".flex.items-center.gap-2", ); const nextRow = allRows?.[entryIndex + 1]; - nextRow?.querySelector('input[placeholder="KEY"]')?.focus(); + nextRow?.querySelector('input[placeholder="KEY_NAME"]')?.focus(); } } else if (e.key === "Escape") { onCancel(); @@ -179,7 +179,7 @@ export function BulkAddEnvVars({ const getErrors = (entry: EnvVarEntry): { key?: string; value?: string } => { const errors: { key?: string; value?: string } = {}; - if (entry.key && !/^[A-Z][A-Z0-9_]*$/.test(entry.key)) { + if (entry.key && !ENV_VAR_KEY_REGEX.test(entry.key)) { errors.key = "Must be UPPERCASE"; } else if (entry.key && getExistingEnvVar(entry.key)) { errors.key = "Already exists"; @@ -233,31 +233,35 @@ export function BulkAddEnvVars({ return (
- updateEntry(entry.id, "key", e.target.value)} - onKeyDown={(e) => handleKeyDown(e, entry.id, "key")} - onPaste={(e) => handlePaste(e, entry.id)} - className={cn( - "w-32 px-2 py-1 text-xs font-mono bg-gray-3 border rounded focus:outline-none focus:ring-1", - errors.key - ? "border-error-9 focus:ring-error-9" - : "border-gray-6 focus:ring-accent-9", - )} - /> - = - + updateEntry(entry.id, "key", e.target.value)} + onKeyDown={(e) => handleKeyDown(e, entry.id, "key")} + onPaste={(e) => handlePaste(e, entry.id)} + className={cn( + "min-h-[32px] text-xs w-[108px] font-mono uppercase", + errors.key && "border-red-6 focus:border-red-7", + )} + autoComplete="off" + spellCheck={false} + /> +
+ = + updateEntry(entry.id, "value", e.target.value)} onKeyDown={(e) => handleKeyDown(e, entry.id, "value")} onPaste={(e) => handlePaste(e, entry.id)} - className="flex-1 px-2 py-1 text-xs font-mono bg-gray-3 border border-gray-6 rounded focus:outline-none focus:ring-1 focus:ring-accent-9" + className="min-h-[32px] text-xs flex-1 font-mono" + autoComplete={entry.type === "writeonly" ? "new-password" : "off"} + spellCheck={false} /> -
+