From 9679213e8634c67be7cc5378e71a3503ff9e39da Mon Sep 17 00:00:00 2001 From: worstell Date: Thu, 8 Aug 2024 13:33:45 -0700 Subject: [PATCH 01/35] fix: maybe fix rare npe (#2259) still haven't been able to repro but attempts to fix #2251 --- go-runtime/schema/extract.go | 86 ++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/go-runtime/schema/extract.go b/go-runtime/schema/extract.go index d66eaf52cf..56091af5e2 100644 --- a/go-runtime/schema/extract.go +++ b/go-runtime/schema/extract.go @@ -41,43 +41,47 @@ import ( // It is a list of lists, where each list is a round of tasks dependent on the prior round's execution (e.g. an analyzer // in Extractors[1] will only execute once all analyzers in Extractors[0] complete). Elements of the same list // should be considered unordered and may run in parallel. -var Extractors = [][]*analysis.Analyzer{ - { - initialize.Analyzer, - inspect.Analyzer, - }, - { - metadata.Extractor, - }, - { - // must run before typeenumvariant.Extractor; typeenum.Extractor determines all possible discriminator - // interfaces and typeenumvariant.Extractor determines any types that implement these - typeenum.Extractor, - }, - { - configsecret.Extractor, - data.Extractor, - database.Extractor, - fsm.Extractor, - topic.Extractor, - typealias.Extractor, - typeenumvariant.Extractor, - valueenumvariant.Extractor, - verb.Extractor, - }, - { - call.Extractor, - // must run after valueenumvariant.Extractor and typeenumvariant.Extractor; - // visits a node and aggregates its enum variants if present - enum.Extractor, - subscription.Extractor, - }, - { - transitive.Extractor, - }, - { - finalize.Analyzer, - }, +var Extractors [][]*analysis.Analyzer + +func init() { + Extractors = [][]*analysis.Analyzer{ + { + initialize.Analyzer, + inspect.Analyzer, + }, + { + metadata.Extractor, + }, + { + // must run before typeenumvariant.Extractor; typeenum.Extractor determines all possible discriminator + // interfaces and typeenumvariant.Extractor determines any types that implement these + typeenum.Extractor, + }, + { + configsecret.Extractor, + data.Extractor, + database.Extractor, + fsm.Extractor, + topic.Extractor, + typealias.Extractor, + typeenumvariant.Extractor, + valueenumvariant.Extractor, + verb.Extractor, + }, + { + call.Extractor, + // must run after valueenumvariant.Extractor and typeenumvariant.Extractor; + // visits a node and aggregates its enum variants if present + enum.Extractor, + subscription.Extractor, + }, + { + transitive.Extractor, + }, + { + finalize.Analyzer, + }, + } } // NativeNames is a map of top-level declarations to their native Go names. @@ -297,7 +301,13 @@ func analyzersWithDependencies() []*analysis.Analyzer { func dependenciesBeforeIndex(idx int) []*analysis.Analyzer { var deps []*analysis.Analyzer for i := range idx { - deps = append(deps, Extractors[i]...) + for _, extractor := range Extractors[i] { + if extractor == nil { + panic(fmt.Sprintf("analyzer at Extractors[%d] not yet initialized", i)) + } + + deps = append(deps, extractor) + } } return deps } From bdc2dae360ccb553b8cbe294a523dd51be299707 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Fri, 9 Aug 2024 08:55:53 +1000 Subject: [PATCH 02/35] refactor: switch from pgx5 to stdlib sql driver (#2299) This will allow us to trivially add OTEL instrumentation. --- backend/controller/controller.go | 16 +- backend/controller/cronjobs/cronjobs.go | 6 +- backend/controller/cronjobs/dal/dal.go | 9 +- backend/controller/cronjobs/sql/db.go | 13 +- backend/controller/cronjobs/sql/models.go | 26 +- backend/controller/cronjobs/sql/querier.go | 3 +- .../controller/cronjobs/sql/queries.sql.go | 23 +- backend/controller/dal/async_calls.go | 17 +- backend/controller/dal/dal.go | 25 +- backend/controller/dal/events.go | 9 +- backend/controller/dal/fsm.go | 5 +- backend/controller/dal/lease.go | 8 +- backend/controller/dal/lease_test.go | 2 +- backend/controller/dal/pubsub.go | 9 +- backend/controller/sql/conn.go | 31 +- .../controller/sql/databasetesting/devel.go | 37 ++- backend/controller/sql/db.go | 13 +- backend/controller/sql/models.go | 26 +- backend/controller/sql/querier.go | 25 +- backend/controller/sql/queries.sql.go | 306 +++++++++++------- backend/controller/sql/sqltest/testing.go | 4 +- backend/controller/sql/sqltypes/sqltypes.go | 32 ++ cmd/ftl-controller/main.go | 4 +- cmd/ftl/cmd_box_run.go | 7 +- cmd/ftl/cmd_serve.go | 7 +- common/configuration/dal/dal.go | 5 +- common/configuration/sql/db.go | 13 +- common/configuration/sql/models.go | 26 +- common/configuration/sql/querier.go | 5 +- common/configuration/sql/queries.sql.go | 29 +- go.mod | 3 +- go.sum | 2 + sqlc.yaml | 5 +- 33 files changed, 446 insertions(+), 305 deletions(-) create mode 100644 backend/controller/sql/sqltypes/sqltypes.go diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 28399102a9..e347fa38d9 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -4,6 +4,7 @@ import ( "bytes" "context" sha "crypto/sha256" + "database/sql" "encoding/binary" "encoding/json" "errors" @@ -25,7 +26,6 @@ import ( "github.com/alecthomas/types/either" "github.com/alecthomas/types/optional" "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgxpool" "github.com/jellydator/ttlcache/v3" "github.com/jpillora/backoff" "golang.org/x/exp/maps" @@ -147,7 +147,7 @@ func (c *Config) SetDefaults() { } // Start the Controller. Blocks until the context is cancelled. -func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScaling, pool *pgxpool.Pool, encryptors *dal.Encryptors) error { +func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScaling, conn *sql.DB, encryptors *dal.Encryptors) error { config.SetDefaults() logger := log.FromContext(ctx) @@ -168,7 +168,7 @@ func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScali logger.Infof("Web console available at: %s", config.Bind) } - svc, err := New(ctx, pool, config, runnerScaling, encryptors) + svc, err := New(ctx, conn, config, runnerScaling, encryptors) if err != nil { return err } @@ -226,7 +226,7 @@ type ControllerListListener interface { } type Service struct { - pool *pgxpool.Pool + conn *sql.DB dal *dal.DAL key model.ControllerKey deploymentLogsSink *deploymentLogsSink @@ -250,7 +250,7 @@ type Service struct { asyncCallsLock sync.Mutex } -func New(ctx context.Context, pool *pgxpool.Pool, config Config, runnerScaling scaling.RunnerScaling, encryptors *dal.Encryptors) (*Service, error) { +func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling.RunnerScaling, encryptors *dal.Encryptors) (*Service, error) { key := config.Key if config.Key.IsZero() { key = model.NewControllerKey(config.Bind.Hostname(), config.Bind.Port()) @@ -264,7 +264,7 @@ func New(ctx context.Context, pool *pgxpool.Pool, config Config, runnerScaling s config.ControllerTimeout = time.Second * 5 } - db, err := dal.New(ctx, pool, encryptors) + db, err := dal.New(ctx, conn, encryptors) if err != nil { return nil, fmt.Errorf("failed to create DAL: %w", err) } @@ -272,7 +272,7 @@ func New(ctx context.Context, pool *pgxpool.Pool, config Config, runnerScaling s svc := &Service{ tasks: scheduledtask.New(ctx, key, db), dal: db, - pool: pool, + conn: conn, key: key, deploymentLogsSink: newDeploymentLogsSink(ctx, db), clients: ttlcache.New(ttlcache.WithTTL[string, clients](time.Minute)), @@ -283,7 +283,7 @@ func New(ctx context.Context, pool *pgxpool.Pool, config Config, runnerScaling s svc.routes.Store(map[string][]dal.Route{}) svc.schema.Store(&schema.Schema{}) - cronSvc := cronjobs.New(ctx, key, svc.config.Advertise.Host, cronjobs.Config{Timeout: config.CronJobTimeout}, pool, svc.tasks, svc.callWithRequest) + cronSvc := cronjobs.New(ctx, key, svc.config.Advertise.Host, cronjobs.Config{Timeout: config.CronJobTimeout}, conn, svc.tasks, svc.callWithRequest) svc.cronJobs = cronSvc svc.controllerListListeners = append(svc.controllerListListeners, cronSvc) diff --git a/backend/controller/cronjobs/cronjobs.go b/backend/controller/cronjobs/cronjobs.go index 1f555a1f79..c892c7000f 100644 --- a/backend/controller/cronjobs/cronjobs.go +++ b/backend/controller/cronjobs/cronjobs.go @@ -2,6 +2,7 @@ package cronjobs import ( "context" + "database/sql" "encoding/json" "errors" "fmt" @@ -12,7 +13,6 @@ import ( "github.com/alecthomas/types/optional" "github.com/alecthomas/types/pubsub" "github.com/benbjohnson/clock" - "github.com/jackc/pgx/v5/pgxpool" "github.com/jpillora/backoff" "github.com/serialx/hashring" @@ -97,8 +97,8 @@ type Service struct { hashRingState atomic.Value[*hashRingState] } -func New(ctx context.Context, key model.ControllerKey, requestSource string, config Config, pool *pgxpool.Pool, scheduler Scheduler, call ExecuteCallFunc) *Service { - return NewForTesting(ctx, key, requestSource, config, dal.New(pool), scheduler, call, clock.New()) +func New(ctx context.Context, key model.ControllerKey, requestSource string, config Config, conn *sql.DB, scheduler Scheduler, call ExecuteCallFunc) *Service { + return NewForTesting(ctx, key, requestSource, config, dal.New(conn), scheduler, call, clock.New()) } func NewForTesting(ctx context.Context, key model.ControllerKey, requestSource string, config Config, dal DAL, scheduler Scheduler, call ExecuteCallFunc, clock clock.Clock) *Service { diff --git a/backend/controller/cronjobs/dal/dal.go b/backend/controller/cronjobs/dal/dal.go index 9408465204..9499717fe6 100644 --- a/backend/controller/cronjobs/dal/dal.go +++ b/backend/controller/cronjobs/dal/dal.go @@ -6,9 +6,8 @@ import ( "fmt" "time" - "github.com/jackc/pgx/v5/pgxpool" - "github.com/TBD54566975/ftl/backend/controller/cronjobs/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" @@ -19,8 +18,8 @@ type DAL struct { db sql.DBI } -func New(pool *pgxpool.Pool) *DAL { - return &DAL{db: sql.NewDB(pool)} +func New(conn sql.ConnI) *DAL { + return &DAL{db: sql.NewDB(conn)} } func cronJobFromRow(row sql.GetCronJobsRow) model.CronJob { @@ -92,7 +91,7 @@ func (d *DAL) EndCronJob(ctx context.Context, job model.CronJob, next time.Time) // GetStaleCronJobs returns a list of cron jobs that have been executing longer than the duration func (d *DAL) GetStaleCronJobs(ctx context.Context, duration time.Duration) ([]model.CronJob, error) { - rows, err := d.db.GetStaleCronJobs(ctx, duration) + rows, err := d.db.GetStaleCronJobs(ctx, sqltypes.Duration(duration)) if err != nil { return nil, fmt.Errorf("failed to get stale cron jobs: %w", dalerrs.TranslatePGError(err)) } diff --git a/backend/controller/cronjobs/sql/db.go b/backend/controller/cronjobs/sql/db.go index c4b45fb311..8a1e45d051 100644 --- a/backend/controller/cronjobs/sql/db.go +++ b/backend/controller/cronjobs/sql/db.go @@ -6,15 +6,14 @@ package sql import ( "context" - - "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgconn" + "database/sql" ) type DBTX interface { - Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) - Query(context.Context, string, ...interface{}) (pgx.Rows, error) - QueryRow(context.Context, string, ...interface{}) pgx.Row + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row } func New(db DBTX) *Queries { @@ -25,7 +24,7 @@ type Queries struct { db DBTX } -func (q *Queries) WithTx(tx pgx.Tx) *Queries { +func (q *Queries) WithTx(tx *sql.Tx) *Queries { return &Queries{ db: tx, } diff --git a/backend/controller/cronjobs/sql/models.go b/backend/controller/cronjobs/sql/models.go index e67f71b017..c5bddc7eb9 100644 --- a/backend/controller/cronjobs/sql/models.go +++ b/backend/controller/cronjobs/sql/models.go @@ -11,10 +11,12 @@ import ( "time" "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" ) type AsyncCallState string @@ -376,16 +378,16 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request []byte - Response []byte + Request json.RawMessage + Response pqtype.NullRawMessage Error optional.Option[string] RemainingAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] Catching bool ParentRequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type Controller struct { @@ -415,7 +417,7 @@ type Deployment struct { ModuleID int64 Key model.DeploymentKey Schema *schema.Module - Labels []byte + Labels json.RawMessage MinReplicas int32 } @@ -467,7 +469,7 @@ type Lease struct { Key leases.Key CreatedAt time.Time ExpiresAt time.Time - Metadata []byte + Metadata pqtype.NullRawMessage } type Module struct { @@ -481,7 +483,7 @@ type ModuleConfiguration struct { CreatedAt time.Time Module optional.Option[string] Name string - Value []byte + Value json.RawMessage } type ModuleSecret struct { @@ -509,7 +511,7 @@ type Runner struct { Endpoint string ModuleName optional.Option[string] DeploymentID optional.Option[int64] - Labels []byte + Labels json.RawMessage } type Topic struct { @@ -530,7 +532,7 @@ type TopicEvent struct { Payload []byte Caller optional.Option[string] RequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type TopicSubscriber struct { @@ -541,8 +543,8 @@ type TopicSubscriber struct { DeploymentID int64 Sink schema.RefKey RetryAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] } diff --git a/backend/controller/cronjobs/sql/querier.go b/backend/controller/cronjobs/sql/querier.go index 9f8cb6a55a..319aa22a60 100644 --- a/backend/controller/cronjobs/sql/querier.go +++ b/backend/controller/cronjobs/sql/querier.go @@ -8,6 +8,7 @@ import ( "context" "time" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/internal/model" ) @@ -15,7 +16,7 @@ type Querier interface { CreateCronJob(ctx context.Context, arg CreateCronJobParams) error EndCronJob(ctx context.Context, nextExecution time.Time, key model.CronJobKey, startTime time.Time) (EndCronJobRow, error) GetCronJobs(ctx context.Context) ([]GetCronJobsRow, error) - GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) ([]GetStaleCronJobsRow, error) + GetStaleCronJobs(ctx context.Context, dollar_1 sqltypes.Duration) ([]GetStaleCronJobsRow, error) StartCronJobs(ctx context.Context, keys []string) ([]StartCronJobsRow, error) } diff --git a/backend/controller/cronjobs/sql/queries.sql.go b/backend/controller/cronjobs/sql/queries.sql.go index 5199dc158a..fe741663db 100644 --- a/backend/controller/cronjobs/sql/queries.sql.go +++ b/backend/controller/cronjobs/sql/queries.sql.go @@ -9,7 +9,9 @@ import ( "context" "time" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/internal/model" + "github.com/lib/pq" ) const createCronJob = `-- name: CreateCronJob :exec @@ -35,7 +37,7 @@ type CreateCronJobParams struct { } func (q *Queries) CreateCronJob(ctx context.Context, arg CreateCronJobParams) error { - _, err := q.db.Exec(ctx, createCronJob, + _, err := q.db.ExecContext(ctx, createCronJob, arg.Key, arg.DeploymentKey, arg.ModuleName, @@ -75,7 +77,7 @@ type EndCronJobRow struct { } func (q *Queries) EndCronJob(ctx context.Context, nextExecution time.Time, key model.CronJobKey, startTime time.Time) (EndCronJobRow, error) { - row := q.db.QueryRow(ctx, endCronJob, nextExecution, key, startTime) + row := q.db.QueryRowContext(ctx, endCronJob, nextExecution, key, startTime) var i EndCronJobRow err := row.Scan( &i.Key, @@ -109,7 +111,7 @@ type GetCronJobsRow struct { } func (q *Queries) GetCronJobs(ctx context.Context) ([]GetCronJobsRow, error) { - rows, err := q.db.Query(ctx, getCronJobs) + rows, err := q.db.QueryContext(ctx, getCronJobs) if err != nil { return nil, err } @@ -131,6 +133,9 @@ func (q *Queries) GetCronJobs(ctx context.Context) ([]GetCronJobsRow, error) { } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -156,8 +161,8 @@ type GetStaleCronJobsRow struct { State model.CronJobState } -func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) ([]GetStaleCronJobsRow, error) { - rows, err := q.db.Query(ctx, getStaleCronJobs, dollar_1) +func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 sqltypes.Duration) ([]GetStaleCronJobsRow, error) { + rows, err := q.db.QueryContext(ctx, getStaleCronJobs, dollar_1) if err != nil { return nil, err } @@ -179,6 +184,9 @@ func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -221,7 +229,7 @@ type StartCronJobsRow struct { } func (q *Queries) StartCronJobs(ctx context.Context, keys []string) ([]StartCronJobsRow, error) { - rows, err := q.db.Query(ctx, startCronJobs, keys) + rows, err := q.db.QueryContext(ctx, startCronJobs, pq.Array(keys)) if err != nil { return nil, err } @@ -245,6 +253,9 @@ func (q *Queries) StartCronJobs(ctx context.Context, keys []string) ([]StartCron } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } diff --git a/backend/controller/dal/async_calls.go b/backend/controller/dal/async_calls.go index 02c576f932..696bb9fdf3 100644 --- a/backend/controller/dal/async_calls.go +++ b/backend/controller/dal/async_calls.go @@ -12,6 +12,7 @@ import ( "github.com/alecthomas/types/optional" "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" ) @@ -101,7 +102,7 @@ func (d *DAL) AcquireAsyncCall(ctx context.Context) (call *AsyncCall, err error) defer tx.CommitOrRollback(ctx, &err) ttl := time.Second * 5 - row, err := tx.db.AcquireAsyncCall(ctx, ttl) + row, err := tx.db.AcquireAsyncCall(ctx, sqltypes.Duration(ttl)) if err != nil { err = dalerrs.TranslatePGError(err) if errors.Is(err, dalerrs.ErrNotFound) { @@ -131,11 +132,11 @@ func (d *DAL) AcquireAsyncCall(ctx context.Context) (call *AsyncCall, err error) ScheduledAt: row.ScheduledAt, QueueDepth: row.QueueDepth, ParentRequestKey: row.ParentRequestKey, - TraceContext: row.TraceContext, + TraceContext: row.TraceContext.RawMessage, RemainingAttempts: row.RemainingAttempts, Error: row.Error, - Backoff: row.Backoff, - MaxBackoff: row.MaxBackoff, + Backoff: time.Duration(row.Backoff), + MaxBackoff: time.Duration(row.MaxBackoff), Catching: row.Catching, }, nil } @@ -169,8 +170,8 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, ID: call.ID, Error: result.Get(), RemainingAttempts: call.RemainingAttempts - 1, - Backoff: min(call.Backoff*2, call.MaxBackoff), - MaxBackoff: call.MaxBackoff, + Backoff: sqltypes.Duration(min(call.Backoff*2, call.MaxBackoff)), + MaxBackoff: sqltypes.Duration(call.MaxBackoff), ScheduledAt: time.Now().Add(call.Backoff), }) if err != nil { @@ -190,8 +191,8 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, ID: call.ID, Error: result.Get(), RemainingAttempts: 0, - Backoff: call.Backoff, // maintain backoff - MaxBackoff: call.MaxBackoff, + Backoff: sqltypes.Duration(call.Backoff), // maintain backoff + MaxBackoff: sqltypes.Duration(call.MaxBackoff), ScheduledAt: scheduledAt, Catching: true, OriginalError: optional.Some(originalError), diff --git a/backend/controller/dal/dal.go b/backend/controller/dal/dal.go index 1ea5f6daf0..6a8d625750 100644 --- a/backend/controller/dal/dal.go +++ b/backend/controller/dal/dal.go @@ -3,6 +3,7 @@ package dal import ( "context" + stdsql "database/sql" "encoding/json" "errors" "fmt" @@ -13,10 +14,10 @@ import ( "github.com/alecthomas/types/optional" "github.com/alecthomas/types/pubsub" sets "github.com/deckarep/golang-set/v2" - "github.com/jackc/pgx/v5/pgxpool" "google.golang.org/protobuf/proto" "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/schema" @@ -209,18 +210,12 @@ func WithReservation(ctx context.Context, reservation Reservation, fn func() err return reservation.Commit(ctx) } -func New(ctx context.Context, pool *pgxpool.Pool, encryptors *Encryptors) (*DAL, error) { - _, err := pool.Acquire(ctx) - if err != nil { - return nil, fmt.Errorf("could not acquire connection: %w", err) - } - dal := &DAL{ - db: sql.NewDB(pool), +func New(ctx context.Context, conn *stdsql.DB, encryptors *Encryptors) (*DAL, error) { + return &DAL{ + db: sql.NewDB(conn), DeploymentChanges: pubsub.New[DeploymentNotification](), encryptors: encryptors, - } - - return dal, nil + }, nil } type DAL struct { @@ -602,13 +597,13 @@ func (d *DAL) UpsertRunner(ctx context.Context, runner Runner) error { // KillStaleRunners deletes runners that have not had heartbeats for the given duration. func (d *DAL) KillStaleRunners(ctx context.Context, age time.Duration) (int64, error) { - count, err := d.db.KillStaleRunners(ctx, age) + count, err := d.db.KillStaleRunners(ctx, sqltypes.Duration(age)) return count, err } // KillStaleControllers deletes controllers that have not had heartbeats for the given duration. func (d *DAL) KillStaleControllers(ctx context.Context, age time.Duration) (int64, error) { - count, err := d.db.KillStaleControllers(ctx, age) + count, err := d.db.KillStaleControllers(ctx, sqltypes.Duration(age)) return count, err } @@ -946,7 +941,7 @@ func (d *DAL) GetProcessList(ctx context.Context) ([]Process, error) { var runner optional.Option[ProcessRunner] if endpoint, ok := row.Endpoint.Get(); ok { var labels model.Labels - if err := json.Unmarshal(row.RunnerLabels, &labels); err != nil { + if err := json.Unmarshal(row.RunnerLabels.RawMessage, &labels); err != nil { return Process{}, fmt.Errorf("invalid labels JSON for runner %s: %w", row.RunnerKey, err) } @@ -1170,7 +1165,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { } func (d *DAL) DeleteOldEvents(ctx context.Context, eventType EventType, age time.Duration) (int64, error) { - count, err := d.db.DeleteOldEvents(ctx, age, eventType) + count, err := d.db.DeleteOldEvents(ctx, sqltypes.Duration(age), eventType) return count, dalerrs.TranslatePGError(err) } diff --git a/backend/controller/dal/events.go b/backend/controller/dal/events.go index 7250e047ac..8889d1c433 100644 --- a/backend/controller/dal/events.go +++ b/backend/controller/dal/events.go @@ -2,13 +2,13 @@ package dal import ( "context" + stdsql "database/sql" "encoding/json" "fmt" "strconv" "time" "github.com/alecthomas/types/optional" - "github.com/jackc/pgx/v5" "github.com/TBD54566975/ftl/backend/controller/sql" dalerrs "github.com/TBD54566975/ftl/backend/dal" @@ -260,10 +260,11 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter deploymentQuery += ` WHERE key = ANY($1::TEXT[])` deploymentArgs = append(deploymentArgs, filter.deployments) } - rows, err := d.db.Conn().Query(ctx, deploymentQuery, deploymentArgs...) + rows, err := d.db.Conn().QueryContext(ctx, deploymentQuery, deploymentArgs...) if err != nil { return nil, dalerrs.TranslatePGError(err) } + defer rows.Close() // nolint:errcheck deploymentIDs := []int64{} for rows.Next() { var id int64 @@ -315,7 +316,7 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter q += fmt.Sprintf(" LIMIT %d", limit) // Issue query. - rows, err = d.db.Conn().Query(ctx, q, args...) + rows, err = d.db.Conn().QueryContext(ctx, q, args...) if err != nil { return nil, fmt.Errorf("%s: %w", q, dalerrs.TranslatePGError(err)) } @@ -328,7 +329,7 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter return events, nil } -func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey, rows pgx.Rows) ([]Event, error) { +func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey, rows *stdsql.Rows) ([]Event, error) { var out []Event for rows.Next() { row := eventRow{} diff --git a/backend/controller/dal/fsm.go b/backend/controller/dal/fsm.go index 750a94825c..b463b39a5d 100644 --- a/backend/controller/dal/fsm.go +++ b/backend/controller/dal/fsm.go @@ -12,6 +12,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/leases" "github.com/TBD54566975/ftl/backend/controller/observability" "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" ) @@ -42,8 +43,8 @@ func (d *DAL) StartFSMTransition(ctx context.Context, fsm schema.RefKey, executi Origin: origin.String(), Request: encryptedRequest, RemainingAttempts: int32(retryParams.Count), - Backoff: retryParams.MinBackoff, - MaxBackoff: retryParams.MaxBackoff, + Backoff: sqltypes.Duration(retryParams.MinBackoff), + MaxBackoff: sqltypes.Duration(retryParams.MaxBackoff), CatchVerb: retryParams.Catch, }) observability.AsyncCalls.Created(ctx, destinationState, retryParams.Catch, origin.String(), int64(retryParams.Count), err) diff --git a/backend/controller/dal/lease.go b/backend/controller/dal/lease.go index d29625764c..7bcfc64fc0 100644 --- a/backend/controller/dal/lease.go +++ b/backend/controller/dal/lease.go @@ -9,9 +9,11 @@ import ( "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" "github.com/TBD54566975/ftl/backend/controller/leases" "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/internal/log" ) @@ -44,7 +46,7 @@ func (l *Lease) renew(ctx context.Context, cancelCtx context.CancelFunc) { case <-time.After(leaseRenewalInterval): logger.Tracef("Renewing lease") ctx, cancel := context.WithTimeout(ctx, leaseRenewalInterval) - _, err := l.db.RenewLease(ctx, l.ttl, l.idempotencyKey, l.key) + _, err := l.db.RenewLease(ctx, sqltypes.Duration(l.ttl), l.idempotencyKey, l.key) cancel() if err != nil { @@ -94,7 +96,7 @@ func (d *DAL) AcquireLease(ctx context.Context, key leases.Key, ttl time.Duratio return nil, nil, fmt.Errorf("failed to marshal lease metadata: %w", err) } } - idempotencyKey, err := d.db.NewLease(ctx, key, ttl, metadataBytes) + idempotencyKey, err := d.db.NewLease(ctx, key, sqltypes.Duration(ttl), pqtype.NullRawMessage{RawMessage: metadataBytes}) if err != nil { err = dalerrs.TranslatePGError(err) if errors.Is(err, dalerrs.ErrConflict) { @@ -128,7 +130,7 @@ func (d *DAL) GetLeaseInfo(ctx context.Context, key leases.Key, metadata any) (e if err != nil { return expiry, dalerrs.TranslatePGError(err) } - if err := json.Unmarshal(l.Metadata, metadata); err != nil { + if err := json.Unmarshal(l.Metadata.RawMessage, metadata); err != nil { return expiry, fmt.Errorf("could not unmarshal lease metadata: %w", err) } return l.ExpiresAt, nil diff --git a/backend/controller/dal/lease_test.go b/backend/controller/dal/lease_test.go index 5b73d84bbe..0c6531cec6 100644 --- a/backend/controller/dal/lease_test.go +++ b/backend/controller/dal/lease_test.go @@ -21,7 +21,7 @@ func leaseExists(t *testing.T, conn sql.ConnI, idempotencyKey uuid.UUID, key lea t.Helper() var count int err := dalerrs.TranslatePGError(conn. - QueryRow(context.Background(), "SELECT COUNT(*) FROM leases WHERE idempotency_key = $1 AND key = $2", idempotencyKey, key). + QueryRowContext(context.Background(), "SELECT COUNT(*) FROM leases WHERE idempotency_key = $1 AND key = $2", idempotencyKey, key). Scan(&count)) if errors.Is(err, dalerrs.ErrNotFound) { return false diff --git a/backend/controller/dal/pubsub.go b/backend/controller/dal/pubsub.go index 699799daee..6672482627 100644 --- a/backend/controller/dal/pubsub.go +++ b/backend/controller/dal/pubsub.go @@ -11,6 +11,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/observability" "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/log" @@ -91,7 +92,7 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t successful := 0 for _, subscription := range subs { - nextCursor, err := tx.db.GetNextEventForSubscription(ctx, eventConsumptionDelay, subscription.Topic, subscription.Cursor) + nextCursor, err := tx.db.GetNextEventForSubscription(ctx, sqltypes.Duration(eventConsumptionDelay), subscription.Topic, subscription.Cursor) if err != nil { observability.PubSub.PropagationFailed(ctx, "GetNextEventForSubscription", subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), optional.None[schema.RefKey]()) return 0, fmt.Errorf("failed to get next cursor: %w", dalerrs.TranslatePGError(err)) @@ -133,7 +134,7 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t Backoff: subscriber.Backoff, MaxBackoff: subscriber.MaxBackoff, ParentRequestKey: nextCursor.RequestKey, - TraceContext: nextCursor.TraceContext, + TraceContext: nextCursor.TraceContext.RawMessage, CatchVerb: subscriber.CatchVerb, }) observability.AsyncCalls.Created(ctx, subscriber.Sink, subscriber.CatchVerb, origin.String(), int64(subscriber.RetryAttempts), err) @@ -300,8 +301,8 @@ func (d *DAL) createSubscribers(ctx context.Context, tx *sql.Tx, key model.Deplo Deployment: key, Sink: sinkRef, RetryAttempts: int32(retryParams.Count), - Backoff: retryParams.MinBackoff, - MaxBackoff: retryParams.MaxBackoff, + Backoff: sqltypes.Duration(retryParams.MinBackoff), + MaxBackoff: sqltypes.Duration(retryParams.MaxBackoff), CatchVerb: retryParams.Catch, }) if err != nil { diff --git a/backend/controller/sql/conn.go b/backend/controller/sql/conn.go index 5a2498536e..d3a29c87cf 100644 --- a/backend/controller/sql/conn.go +++ b/backend/controller/sql/conn.go @@ -2,10 +2,9 @@ package sql import ( "context" + "database/sql" "errors" "fmt" - - "github.com/jackc/pgx/v5" ) type DBI interface { @@ -16,7 +15,7 @@ type DBI interface { type ConnI interface { DBTX - Begin(ctx context.Context) (pgx.Tx, error) + Begin() (*sql.Tx, error) } type DB struct { @@ -31,32 +30,36 @@ func NewDB(conn ConnI) *DB { func (d *DB) Conn() ConnI { return d.conn } func (d *DB) Begin(ctx context.Context) (*Tx, error) { - tx, err := d.conn.Begin(ctx) + tx, err := d.conn.Begin() if err != nil { return nil, err } return &Tx{tx: tx, Queries: New(tx)}, nil } +type noopSubConn struct { + DBTX +} + +func (noopSubConn) Begin() (*sql.Tx, error) { + return nil, errors.New("sql: not implemented") +} + type Tx struct { - tx pgx.Tx + tx *sql.Tx *Queries } -func (t *Tx) Conn() ConnI { return t.tx } +func (t *Tx) Conn() ConnI { return noopSubConn{t.tx} } -func (t *Tx) Tx() pgx.Tx { return t.tx } +func (t *Tx) Tx() *sql.Tx { return t.tx } func (t *Tx) Begin(ctx context.Context) (*Tx, error) { - _, err := t.tx.Begin(ctx) - if err != nil { - return nil, fmt.Errorf("beginning transaction: %w", err) - } - return &Tx{tx: t.tx, Queries: t.Queries}, nil + return nil, fmt.Errorf("cannot nest transactions") } func (t *Tx) Commit(ctx context.Context) error { - err := t.tx.Commit(ctx) + err := t.tx.Commit() if err != nil { return fmt.Errorf("committing transaction: %w", err) } @@ -65,7 +68,7 @@ func (t *Tx) Commit(ctx context.Context) error { } func (t *Tx) Rollback(ctx context.Context) error { - err := t.tx.Rollback(ctx) + err := t.tx.Rollback() if err != nil { return fmt.Errorf("rolling back transaction: %w", err) } diff --git a/backend/controller/sql/databasetesting/devel.go b/backend/controller/sql/databasetesting/devel.go index 96f6cb44c9..b1c4e3dd18 100644 --- a/backend/controller/sql/databasetesting/devel.go +++ b/backend/controller/sql/databasetesting/devel.go @@ -2,11 +2,13 @@ package databasetesting import ( "context" + stdsql "database/sql" "fmt" + "net/url" + "strings" "time" - "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgxpool" + _ "github.com/jackc/pgx/v5/stdlib" // pgx driver "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/internal/log" @@ -15,20 +17,21 @@ import ( // CreateForDevel creates and migrates a new database for development or testing. // // If "recreate" is true, the database will be dropped and recreated. -func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*pgxpool.Pool, error) { +func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*stdsql.DB, error) { logger := log.FromContext(ctx) - config, err := pgx.ParseConfig(dsn) + config, err := url.Parse(dsn) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse DSN: %w", err) } - noDBDSN := config.Copy() - noDBDSN.Database = "" - var conn *pgx.Conn + noDBDSN := *config + noDBDSN.Path = "" // Remove the database name. + + var conn *stdsql.DB for range 10 { - conn, err = pgx.ConnectConfig(ctx, noDBDSN) + conn, err = stdsql.Open("pgx", noDBDSN.String()) if err == nil { - defer conn.Close(ctx) + defer conn.Close() break } logger.Debugf("Waiting for database to be ready: %v", err) @@ -43,31 +46,33 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*pgxpool.Po return nil, fmt.Errorf("database not ready after 10 tries: %w", err) } + dbName := strings.TrimPrefix(config.Path, "/") + if recreate { // Terminate any dangling connections. - _, err = conn.Exec(ctx, ` + _, err = conn.ExecContext(ctx, ` SELECT pid, pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`, - config.Database) + dbName) if err != nil { return nil, err } - _, err = conn.Exec(ctx, fmt.Sprintf("DROP DATABASE IF EXISTS %q", config.Database)) + _, err = conn.ExecContext(ctx, fmt.Sprintf("DROP DATABASE IF EXISTS %q", dbName)) if err != nil { return nil, err } } - _, _ = conn.Exec(ctx, fmt.Sprintf("CREATE DATABASE %q", config.Database)) //nolint:errcheck // PG doesn't support "IF NOT EXISTS" so instead we just ignore any error. + _, _ = conn.ExecContext(ctx, fmt.Sprintf("CREATE DATABASE %q", dbName)) //nolint:errcheck // PG doesn't support "IF NOT EXISTS" so instead we just ignore any error. err = sql.Migrate(ctx, dsn, log.Debug) if err != nil { return nil, err } - realConn, err := pgxpool.New(ctx, dsn) + realConn, err := stdsql.Open("pgx", dsn) if err != nil { return nil, err } @@ -75,7 +80,7 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*pgxpool.Po // This includes things like resetting the state of async calls, leases, // controller/runner registration, etc. but not anything more. if !recreate { - _, err = realConn.Exec(ctx, ` + _, err = realConn.ExecContext(ctx, ` WITH deleted AS ( DELETE FROM async_calls RETURNING 1 diff --git a/backend/controller/sql/db.go b/backend/controller/sql/db.go index c4b45fb311..8a1e45d051 100644 --- a/backend/controller/sql/db.go +++ b/backend/controller/sql/db.go @@ -6,15 +6,14 @@ package sql import ( "context" - - "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgconn" + "database/sql" ) type DBTX interface { - Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) - Query(context.Context, string, ...interface{}) (pgx.Rows, error) - QueryRow(context.Context, string, ...interface{}) pgx.Row + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row } func New(db DBTX) *Queries { @@ -25,7 +24,7 @@ type Queries struct { db DBTX } -func (q *Queries) WithTx(tx pgx.Tx) *Queries { +func (q *Queries) WithTx(tx *sql.Tx) *Queries { return &Queries{ db: tx, } diff --git a/backend/controller/sql/models.go b/backend/controller/sql/models.go index e67f71b017..c5bddc7eb9 100644 --- a/backend/controller/sql/models.go +++ b/backend/controller/sql/models.go @@ -11,10 +11,12 @@ import ( "time" "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" ) type AsyncCallState string @@ -376,16 +378,16 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request []byte - Response []byte + Request json.RawMessage + Response pqtype.NullRawMessage Error optional.Option[string] RemainingAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] Catching bool ParentRequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type Controller struct { @@ -415,7 +417,7 @@ type Deployment struct { ModuleID int64 Key model.DeploymentKey Schema *schema.Module - Labels []byte + Labels json.RawMessage MinReplicas int32 } @@ -467,7 +469,7 @@ type Lease struct { Key leases.Key CreatedAt time.Time ExpiresAt time.Time - Metadata []byte + Metadata pqtype.NullRawMessage } type Module struct { @@ -481,7 +483,7 @@ type ModuleConfiguration struct { CreatedAt time.Time Module optional.Option[string] Name string - Value []byte + Value json.RawMessage } type ModuleSecret struct { @@ -509,7 +511,7 @@ type Runner struct { Endpoint string ModuleName optional.Option[string] DeploymentID optional.Option[int64] - Labels []byte + Labels json.RawMessage } type Topic struct { @@ -530,7 +532,7 @@ type TopicEvent struct { Payload []byte Caller optional.Option[string] RequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type TopicSubscriber struct { @@ -541,8 +543,8 @@ type TopicSubscriber struct { DeploymentID int64 Sink schema.RefKey RetryAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] } diff --git a/backend/controller/sql/querier.go b/backend/controller/sql/querier.go index 1331f7e476..f34f4c44e0 100644 --- a/backend/controller/sql/querier.go +++ b/backend/controller/sql/querier.go @@ -6,19 +6,22 @@ package sql import ( "context" + "encoding/json" "time" "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" ) type Querier interface { // Reserve a pending async call for execution, returning the associated lease // reservation key and accompanying metadata. - AcquireAsyncCall(ctx context.Context, ttl time.Duration) (AcquireAsyncCallRow, error) + AcquireAsyncCall(ctx context.Context, ttl sqltypes.Duration) (AcquireAsyncCallRow, error) AssociateArtefactWithDeployment(ctx context.Context, arg AssociateArtefactWithDeploymentParams) error AsyncCallQueueDepth(ctx context.Context) (int64, error) BeginConsumingTopicEvent(ctx context.Context, subscription model.SubscriptionKey, event model.TopicEventKey) error @@ -30,7 +33,7 @@ type Querier interface { CreateDeployment(ctx context.Context, moduleName string, schema []byte, key model.DeploymentKey) error CreateIngressRoute(ctx context.Context, arg CreateIngressRouteParams) error CreateRequest(ctx context.Context, origin Origin, key model.RequestKey, sourceAddr string) error - DeleteOldEvents(ctx context.Context, timeout time.Duration, type_ EventType) (int64, error) + DeleteOldEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) DeleteSubscribers(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriberKey, error) DeleteSubscriptions(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriptionKey, error) DeregisterRunner(ctx context.Context, key model.RunnerKey) (int64, error) @@ -62,12 +65,12 @@ type Querier interface { GetDeploymentsWithMinReplicas(ctx context.Context) ([]GetDeploymentsWithMinReplicasRow, error) GetExistingDeploymentForModule(ctx context.Context, name string) (GetExistingDeploymentForModuleRow, error) GetFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (FsmInstance, error) - GetIdleRunners(ctx context.Context, labels []byte, limit int64) ([]Runner, error) + GetIdleRunners(ctx context.Context, labels json.RawMessage, limit int64) ([]Runner, error) // Get the runner endpoints corresponding to the given ingress route. GetIngressRoutes(ctx context.Context, method string) ([]GetIngressRoutesRow, error) GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) GetModulesByID(ctx context.Context, ids []int64) ([]Module, error) - GetNextEventForSubscription(ctx context.Context, consumptionDelay time.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) + GetNextEventForSubscription(ctx context.Context, consumptionDelay sqltypes.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) GetProcessList(ctx context.Context) ([]GetProcessListRow, error) GetRandomSubscriber(ctx context.Context, key model.SubscriptionKey) (GetRandomSubscriberRow, error) // Retrieve routing information for a runner. @@ -77,7 +80,7 @@ type Querier interface { GetRunnerState(ctx context.Context, key model.RunnerKey) (RunnerState, error) GetRunnersForDeployment(ctx context.Context, key model.DeploymentKey) ([]GetRunnersForDeploymentRow, error) GetSchemaForDeployment(ctx context.Context, key model.DeploymentKey) (*schema.Module, error) - GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) ([]GetStaleCronJobsRow, error) + GetStaleCronJobs(ctx context.Context, dollar_1 sqltypes.Duration) ([]GetStaleCronJobsRow, error) GetSubscription(ctx context.Context, column1 string, column2 string) (TopicSubscription, error) // Results may not be ready to be scheduled yet due to event consumption delay // Sorting ensures that brand new events (that may not be ready for consumption) @@ -92,15 +95,15 @@ type Querier interface { InsertLogEvent(ctx context.Context, arg InsertLogEventParams) error InsertSubscriber(ctx context.Context, arg InsertSubscriberParams) error // Mark any controller entries that haven't been updated recently as dead. - KillStaleControllers(ctx context.Context, timeout time.Duration) (int64, error) - KillStaleRunners(ctx context.Context, timeout time.Duration) (int64, error) + KillStaleControllers(ctx context.Context, timeout sqltypes.Duration) (int64, error) + KillStaleRunners(ctx context.Context, timeout sqltypes.Duration) (int64, error) LoadAsyncCall(ctx context.Context, id int64) (AsyncCall, error) - NewLease(ctx context.Context, key leases.Key, ttl time.Duration, metadata []byte) (uuid.UUID, error) + NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) PublishEventForTopic(ctx context.Context, arg PublishEventForTopicParams) error ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) - RenewLease(ctx context.Context, ttl time.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) + RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) // Find an idle runner and reserve it for the given deployment. - ReserveRunner(ctx context.Context, reservationTimeout time.Time, deploymentKey model.DeploymentKey, labels []byte) (Runner, error) + ReserveRunner(ctx context.Context, reservationTimeout time.Time, deploymentKey model.DeploymentKey, labels json.RawMessage) (Runner, error) SetDeploymentDesiredReplicas(ctx context.Context, key model.DeploymentKey, minReplicas int32) error SetSubscriptionCursor(ctx context.Context, column1 model.SubscriptionKey, column2 model.TopicEventKey) error StartCronJobs(ctx context.Context, keys []string) ([]StartCronJobsRow, error) @@ -108,7 +111,7 @@ type Querier interface { // // "key" is the unique identifier for the FSM execution. StartFSMTransition(ctx context.Context, arg StartFSMTransitionParams) (FsmInstance, error) - SucceedAsyncCall(ctx context.Context, response []byte, iD int64) (bool, error) + SucceedAsyncCall(ctx context.Context, response json.RawMessage, iD int64) (bool, error) SucceedFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (bool, error) UpsertController(ctx context.Context, key model.ControllerKey, endpoint string) (int64, error) UpsertModule(ctx context.Context, language string, name string) (int64, error) diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index a7815e1184..224402327f 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -11,10 +11,13 @@ import ( "time" "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/lib/pq" + "github.com/sqlc-dev/pqtype" ) const acquireAsyncCall = `-- name: AcquireAsyncCall :one @@ -64,21 +67,21 @@ type AcquireAsyncCallRow struct { Origin string Verb schema.RefKey CatchVerb optional.Option[schema.RefKey] - Request []byte + Request json.RawMessage ScheduledAt time.Time RemainingAttempts int32 Error optional.Option[string] - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration ParentRequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage Catching bool } // Reserve a pending async call for execution, returning the associated lease // reservation key and accompanying metadata. -func (q *Queries) AcquireAsyncCall(ctx context.Context, ttl time.Duration) (AcquireAsyncCallRow, error) { - row := q.db.QueryRow(ctx, acquireAsyncCall, ttl) +func (q *Queries) AcquireAsyncCall(ctx context.Context, ttl sqltypes.Duration) (AcquireAsyncCallRow, error) { + row := q.db.QueryRowContext(ctx, acquireAsyncCall, ttl) var i AcquireAsyncCallRow err := row.Scan( &i.AsyncCallID, @@ -114,7 +117,7 @@ type AssociateArtefactWithDeploymentParams struct { } func (q *Queries) AssociateArtefactWithDeployment(ctx context.Context, arg AssociateArtefactWithDeploymentParams) error { - _, err := q.db.Exec(ctx, associateArtefactWithDeployment, + _, err := q.db.ExecContext(ctx, associateArtefactWithDeployment, arg.Key, arg.ArtefactID, arg.Executable, @@ -130,7 +133,7 @@ WHERE state = 'pending' AND scheduled_at <= (NOW() AT TIME ZONE 'utc') ` func (q *Queries) AsyncCallQueueDepth(ctx context.Context) (int64, error) { - row := q.db.QueryRow(ctx, asyncCallQueueDepth) + row := q.db.QueryRowContext(ctx, asyncCallQueueDepth) var count int64 err := row.Scan(&count) return count, err @@ -149,7 +152,7 @@ WHERE key = $1::subscription_key ` func (q *Queries) BeginConsumingTopicEvent(ctx context.Context, subscription model.SubscriptionKey, event model.TopicEventKey) error { - _, err := q.db.Exec(ctx, beginConsumingTopicEvent, subscription, event) + _, err := q.db.ExecContext(ctx, beginConsumingTopicEvent, subscription, event) return err } @@ -166,7 +169,7 @@ WHERE name = $1::TEXT ` func (q *Queries) CompleteEventForSubscription(ctx context.Context, name string, module string) error { - _, err := q.db.Exec(ctx, completeEventForSubscription, name, module) + _, err := q.db.ExecContext(ctx, completeEventForSubscription, name, module) return err } @@ -178,7 +181,7 @@ RETURNING id // Create a new artefact and return the artefact ID. func (q *Queries) CreateArtefact(ctx context.Context, digest []byte, content []byte) (int64, error) { - row := q.db.QueryRow(ctx, createArtefact, digest, content) + row := q.db.QueryRowContext(ctx, createArtefact, digest, content) var id int64 err := row.Scan(&id) return id, err @@ -213,17 +216,17 @@ RETURNING id type CreateAsyncCallParams struct { Verb schema.RefKey Origin string - Request []byte + Request json.RawMessage RemainingAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] ParentRequestKey optional.Option[string] - TraceContext []byte + TraceContext json.RawMessage } func (q *Queries) CreateAsyncCall(ctx context.Context, arg CreateAsyncCallParams) (int64, error) { - row := q.db.QueryRow(ctx, createAsyncCall, + row := q.db.QueryRowContext(ctx, createAsyncCall, arg.Verb, arg.Origin, arg.Request, @@ -262,7 +265,7 @@ type CreateCronJobParams struct { } func (q *Queries) CreateCronJob(ctx context.Context, arg CreateCronJobParams) error { - _, err := q.db.Exec(ctx, createCronJob, + _, err := q.db.ExecContext(ctx, createCronJob, arg.Key, arg.DeploymentKey, arg.ModuleName, @@ -280,7 +283,7 @@ VALUES ((SELECT id FROM modules WHERE name = $1::TEXT LIMIT 1), $2::BYTEA, $3::d ` func (q *Queries) CreateDeployment(ctx context.Context, moduleName string, schema []byte, key model.DeploymentKey) error { - _, err := q.db.Exec(ctx, createDeployment, moduleName, schema, key) + _, err := q.db.ExecContext(ctx, createDeployment, moduleName, schema, key) return err } @@ -298,7 +301,7 @@ type CreateIngressRouteParams struct { } func (q *Queries) CreateIngressRoute(ctx context.Context, arg CreateIngressRouteParams) error { - _, err := q.db.Exec(ctx, createIngressRoute, + _, err := q.db.ExecContext(ctx, createIngressRoute, arg.Key, arg.Module, arg.Verb, @@ -314,7 +317,7 @@ VALUES ($1, $2, $3) ` func (q *Queries) CreateRequest(ctx context.Context, origin Origin, key model.RequestKey, sourceAddr string) error { - _, err := q.db.Exec(ctx, createRequest, origin, key, sourceAddr) + _, err := q.db.ExecContext(ctx, createRequest, origin, key, sourceAddr) return err } @@ -329,8 +332,8 @@ SELECT COUNT(*) FROM deleted ` -func (q *Queries) DeleteOldEvents(ctx context.Context, timeout time.Duration, type_ EventType) (int64, error) { - row := q.db.QueryRow(ctx, deleteOldEvents, timeout, type_) +func (q *Queries) DeleteOldEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) { + row := q.db.QueryRowContext(ctx, deleteOldEvents, timeout, type_) var count int64 err := row.Scan(&count) return count, err @@ -347,7 +350,7 @@ RETURNING topic_subscribers.key ` func (q *Queries) DeleteSubscribers(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriberKey, error) { - rows, err := q.db.Query(ctx, deleteSubscribers, deployment) + rows, err := q.db.QueryContext(ctx, deleteSubscribers, deployment) if err != nil { return nil, err } @@ -360,6 +363,9 @@ func (q *Queries) DeleteSubscribers(ctx context.Context, deployment model.Deploy } items = append(items, key) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -377,7 +383,7 @@ RETURNING topic_subscriptions.key ` func (q *Queries) DeleteSubscriptions(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriptionKey, error) { - rows, err := q.db.Query(ctx, deleteSubscriptions, deployment) + rows, err := q.db.QueryContext(ctx, deleteSubscriptions, deployment) if err != nil { return nil, err } @@ -390,6 +396,9 @@ func (q *Queries) DeleteSubscriptions(ctx context.Context, deployment model.Depl } items = append(items, key) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -408,7 +417,7 @@ FROM matches ` func (q *Queries) DeregisterRunner(ctx context.Context, key model.RunnerKey) (int64, error) { - row := q.db.QueryRow(ctx, deregisterRunner, key) + row := q.db.QueryRowContext(ctx, deregisterRunner, key) var count int64 err := row.Scan(&count) return count, err @@ -442,7 +451,7 @@ type EndCronJobRow struct { } func (q *Queries) EndCronJob(ctx context.Context, nextExecution time.Time, key model.CronJobKey, startTime time.Time) (EndCronJobRow, error) { - row := q.db.QueryRow(ctx, endCronJob, nextExecution, key, startTime) + row := q.db.QueryRowContext(ctx, endCronJob, nextExecution, key, startTime) var i EndCronJobRow err := row.Scan( &i.Key, @@ -468,7 +477,7 @@ FROM expired ` func (q *Queries) ExpireLeases(ctx context.Context) (int64, error) { - row := q.db.QueryRow(ctx, expireLeases) + row := q.db.QueryRowContext(ctx, expireLeases) var count int64 err := row.Scan(&count) return count, err @@ -488,7 +497,7 @@ FROM rows ` func (q *Queries) ExpireRunnerReservations(ctx context.Context) (int64, error) { - row := q.db.QueryRow(ctx, expireRunnerReservations) + row := q.db.QueryRowContext(ctx, expireRunnerReservations) var count int64 err := row.Scan(&count) return count, err @@ -504,7 +513,7 @@ RETURNING true ` func (q *Queries) FailAsyncCall(ctx context.Context, error string, iD int64) (bool, error) { - row := q.db.QueryRow(ctx, failAsyncCall, error, iD) + row := q.db.QueryRowContext(ctx, failAsyncCall, error, iD) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -547,8 +556,8 @@ RETURNING true type FailAsyncCallWithRetryParams struct { RemainingAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration ScheduledAt time.Time Catching bool OriginalError optional.Option[string] @@ -557,7 +566,7 @@ type FailAsyncCallWithRetryParams struct { } func (q *Queries) FailAsyncCallWithRetry(ctx context.Context, arg FailAsyncCallWithRetryParams) (bool, error) { - row := q.db.QueryRow(ctx, failAsyncCallWithRetry, + row := q.db.QueryRowContext(ctx, failAsyncCallWithRetry, arg.RemainingAttempts, arg.Backoff, arg.MaxBackoff, @@ -585,7 +594,7 @@ RETURNING true ` func (q *Queries) FailFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (bool, error) { - row := q.db.QueryRow(ctx, failFSMInstance, fsm, key) + row := q.db.QueryRowContext(ctx, failFSMInstance, fsm, key) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -605,7 +614,7 @@ RETURNING true // Mark an FSM transition as completed, updating the current state and clearing the async call ID. func (q *Queries) FinishFSMTransition(ctx context.Context, fsm schema.RefKey, key string) (bool, error) { - row := q.db.QueryRow(ctx, finishFSMTransition, fsm, key) + row := q.db.QueryRowContext(ctx, finishFSMTransition, fsm, key) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -619,7 +628,7 @@ ORDER BY c.key ` func (q *Queries) GetActiveControllers(ctx context.Context) ([]Controller, error) { - rows, err := q.db.Query(ctx, getActiveControllers) + rows, err := q.db.QueryContext(ctx, getActiveControllers) if err != nil { return nil, err } @@ -639,6 +648,9 @@ func (q *Queries) GetActiveControllers(ctx context.Context) ([]Controller, error } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -655,7 +667,7 @@ type GetActiveDeploymentSchemasRow struct { } func (q *Queries) GetActiveDeploymentSchemas(ctx context.Context) ([]GetActiveDeploymentSchemasRow, error) { - rows, err := q.db.Query(ctx, getActiveDeploymentSchemas) + rows, err := q.db.QueryContext(ctx, getActiveDeploymentSchemas) if err != nil { return nil, err } @@ -668,6 +680,9 @@ func (q *Queries) GetActiveDeploymentSchemas(ctx context.Context) ([]GetActiveDe } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -692,7 +707,7 @@ type GetActiveDeploymentsRow struct { } func (q *Queries) GetActiveDeployments(ctx context.Context) ([]GetActiveDeploymentsRow, error) { - rows, err := q.db.Query(ctx, getActiveDeployments) + rows, err := q.db.QueryContext(ctx, getActiveDeployments) if err != nil { return nil, err } @@ -716,6 +731,9 @@ func (q *Queries) GetActiveDeployments(ctx context.Context) ([]GetActiveDeployme } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -738,7 +756,7 @@ type GetActiveIngressRoutesRow struct { } func (q *Queries) GetActiveIngressRoutes(ctx context.Context) ([]GetActiveIngressRoutesRow, error) { - rows, err := q.db.Query(ctx, getActiveIngressRoutes) + rows, err := q.db.QueryContext(ctx, getActiveIngressRoutes) if err != nil { return nil, err } @@ -757,6 +775,9 @@ func (q *Queries) GetActiveIngressRoutes(ctx context.Context) ([]GetActiveIngres } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -783,14 +804,14 @@ type GetActiveRunnersRow struct { RunnerKey model.RunnerKey Endpoint string State RunnerState - Labels []byte + Labels json.RawMessage LastSeen time.Time ModuleName optional.Option[string] DeploymentKey optional.Option[string] } func (q *Queries) GetActiveRunners(ctx context.Context) ([]GetActiveRunnersRow, error) { - rows, err := q.db.Query(ctx, getActiveRunners) + rows, err := q.db.QueryContext(ctx, getActiveRunners) if err != nil { return nil, err } @@ -811,6 +832,9 @@ func (q *Queries) GetActiveRunners(ctx context.Context) ([]GetActiveRunnersRow, } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -824,7 +848,7 @@ WHERE a.id = $3 ` func (q *Queries) GetArtefactContentRange(ctx context.Context, start int32, count int32, iD int64) ([]byte, error) { - row := q.db.QueryRow(ctx, getArtefactContentRange, start, count, iD) + row := q.db.QueryRowContext(ctx, getArtefactContentRange, start, count, iD) var content []byte err := row.Scan(&content) return content, err @@ -843,7 +867,7 @@ type GetArtefactDigestsRow struct { // Return the digests that exist in the database. func (q *Queries) GetArtefactDigests(ctx context.Context, digests [][]byte) ([]GetArtefactDigestsRow, error) { - rows, err := q.db.Query(ctx, getArtefactDigests, digests) + rows, err := q.db.QueryContext(ctx, getArtefactDigests, pq.Array(digests)) if err != nil { return nil, err } @@ -856,6 +880,9 @@ func (q *Queries) GetArtefactDigests(ctx context.Context, digests [][]byte) ([]G } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -881,7 +908,7 @@ type GetCronJobsRow struct { } func (q *Queries) GetCronJobs(ctx context.Context) ([]GetCronJobsRow, error) { - rows, err := q.db.Query(ctx, getCronJobs) + rows, err := q.db.QueryContext(ctx, getCronJobs) if err != nil { return nil, err } @@ -903,6 +930,9 @@ func (q *Queries) GetCronJobs(ctx context.Context) ([]GetCronJobsRow, error) { } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -924,7 +954,7 @@ type GetDeploymentRow struct { } func (q *Queries) GetDeployment(ctx context.Context, key model.DeploymentKey) (GetDeploymentRow, error) { - row := q.db.QueryRow(ctx, getDeployment, key) + row := q.db.QueryRowContext(ctx, getDeployment, key) var i GetDeploymentRow err := row.Scan( &i.Deployment.ID, @@ -959,7 +989,7 @@ type GetDeploymentArtefactsRow struct { // Get all artefacts matching the given digests. func (q *Queries) GetDeploymentArtefacts(ctx context.Context, deploymentID int64) ([]GetDeploymentArtefactsRow, error) { - rows, err := q.db.Query(ctx, getDeploymentArtefacts, deploymentID) + rows, err := q.db.QueryContext(ctx, getDeploymentArtefacts, deploymentID) if err != nil { return nil, err } @@ -979,6 +1009,9 @@ func (q *Queries) GetDeploymentArtefacts(ctx context.Context, deploymentID int64 } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -992,7 +1025,7 @@ WHERE id = ANY ($1::BIGINT[]) ` func (q *Queries) GetDeploymentsByID(ctx context.Context, ids []int64) ([]Deployment, error) { - rows, err := q.db.Query(ctx, getDeploymentsByID, ids) + rows, err := q.db.QueryContext(ctx, getDeploymentsByID, pq.Array(ids)) if err != nil { return nil, err } @@ -1013,6 +1046,9 @@ func (q *Queries) GetDeploymentsByID(ctx context.Context, ids []int64) ([]Deploy } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1042,7 +1078,7 @@ type GetDeploymentsNeedingReconciliationRow struct { // Get deployments that have a mismatch between the number of assigned and required replicas. func (q *Queries) GetDeploymentsNeedingReconciliation(ctx context.Context) ([]GetDeploymentsNeedingReconciliationRow, error) { - rows, err := q.db.Query(ctx, getDeploymentsNeedingReconciliation) + rows, err := q.db.QueryContext(ctx, getDeploymentsNeedingReconciliation) if err != nil { return nil, err } @@ -1061,6 +1097,9 @@ func (q *Queries) GetDeploymentsNeedingReconciliation(ctx context.Context) ([]Ge } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1091,7 +1130,7 @@ type GetDeploymentsWithArtefactsRow struct { // Get all deployments that have artefacts matching the given digests. func (q *Queries) GetDeploymentsWithArtefacts(ctx context.Context, digests [][]byte, schema []byte, count int64) ([]GetDeploymentsWithArtefactsRow, error) { - rows, err := q.db.Query(ctx, getDeploymentsWithArtefacts, digests, schema, count) + rows, err := q.db.QueryContext(ctx, getDeploymentsWithArtefacts, pq.Array(digests), schema, count) if err != nil { return nil, err } @@ -1110,6 +1149,9 @@ func (q *Queries) GetDeploymentsWithArtefacts(ctx context.Context, digests [][]b } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1131,7 +1173,7 @@ type GetDeploymentsWithMinReplicasRow struct { } func (q *Queries) GetDeploymentsWithMinReplicas(ctx context.Context) ([]GetDeploymentsWithMinReplicasRow, error) { - rows, err := q.db.Query(ctx, getDeploymentsWithMinReplicas) + rows, err := q.db.QueryContext(ctx, getDeploymentsWithMinReplicas) if err != nil { return nil, err } @@ -1154,6 +1196,9 @@ func (q *Queries) GetDeploymentsWithMinReplicas(ctx context.Context) ([]GetDeplo } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1175,7 +1220,7 @@ type GetExistingDeploymentForModuleRow struct { ModuleID int64 Key model.DeploymentKey Schema *schema.Module - Labels []byte + Labels json.RawMessage MinReplicas int32 ID_2 int64 Language string @@ -1183,7 +1228,7 @@ type GetExistingDeploymentForModuleRow struct { } func (q *Queries) GetExistingDeploymentForModule(ctx context.Context, name string) (GetExistingDeploymentForModuleRow, error) { - row := q.db.QueryRow(ctx, getExistingDeploymentForModule, name) + row := q.db.QueryRowContext(ctx, getExistingDeploymentForModule, name) var i GetExistingDeploymentForModuleRow err := row.Scan( &i.ID, @@ -1207,7 +1252,7 @@ WHERE fsm = $1::schema_ref AND key = $2 ` func (q *Queries) GetFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (FsmInstance, error) { - row := q.db.QueryRow(ctx, getFSMInstance, fsm, key) + row := q.db.QueryRowContext(ctx, getFSMInstance, fsm, key) var i FsmInstance err := row.Scan( &i.ID, @@ -1231,8 +1276,8 @@ WHERE labels @> $1::jsonb LIMIT $2 ` -func (q *Queries) GetIdleRunners(ctx context.Context, labels []byte, limit int64) ([]Runner, error) { - rows, err := q.db.Query(ctx, getIdleRunners, labels, limit) +func (q *Queries) GetIdleRunners(ctx context.Context, labels json.RawMessage, limit int64) ([]Runner, error) { + rows, err := q.db.QueryContext(ctx, getIdleRunners, labels, limit) if err != nil { return nil, err } @@ -1256,6 +1301,9 @@ func (q *Queries) GetIdleRunners(ctx context.Context, labels []byte, limit int64 } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1282,7 +1330,7 @@ type GetIngressRoutesRow struct { // Get the runner endpoints corresponding to the given ingress route. func (q *Queries) GetIngressRoutes(ctx context.Context, method string) ([]GetIngressRoutesRow, error) { - rows, err := q.db.Query(ctx, getIngressRoutes, method) + rows, err := q.db.QueryContext(ctx, getIngressRoutes, method) if err != nil { return nil, err } @@ -1302,6 +1350,9 @@ func (q *Queries) GetIngressRoutes(ctx context.Context, method string) ([]GetIng } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1314,11 +1365,11 @@ SELECT expires_at, metadata FROM leases WHERE key = $1::lease_key type GetLeaseInfoRow struct { ExpiresAt time.Time - Metadata []byte + Metadata pqtype.NullRawMessage } func (q *Queries) GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) { - row := q.db.QueryRow(ctx, getLeaseInfo, key) + row := q.db.QueryRowContext(ctx, getLeaseInfo, key) var i GetLeaseInfoRow err := row.Scan(&i.ExpiresAt, &i.Metadata) return i, err @@ -1331,7 +1382,7 @@ WHERE id = ANY ($1::BIGINT[]) ` func (q *Queries) GetModulesByID(ctx context.Context, ids []int64) ([]Module, error) { - rows, err := q.db.Query(ctx, getModulesByID, ids) + rows, err := q.db.QueryContext(ctx, getModulesByID, pq.Array(ids)) if err != nil { return nil, err } @@ -1344,6 +1395,9 @@ func (q *Queries) GetModulesByID(ctx context.Context, ids []int64) ([]Module, er } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1379,12 +1433,12 @@ type GetNextEventForSubscriptionRow struct { CreatedAt optional.Option[time.Time] Caller optional.Option[string] RequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage Ready bool } -func (q *Queries) GetNextEventForSubscription(ctx context.Context, consumptionDelay time.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) { - row := q.db.QueryRow(ctx, getNextEventForSubscription, consumptionDelay, topic, cursor) +func (q *Queries) GetNextEventForSubscription(ctx context.Context, consumptionDelay sqltypes.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) { + row := q.db.QueryRowContext(ctx, getNextEventForSubscription, consumptionDelay, topic, cursor) var i GetNextEventForSubscriptionRow err := row.Scan( &i.Event, @@ -1414,14 +1468,14 @@ ORDER BY d.key type GetProcessListRow struct { MinReplicas int32 DeploymentKey model.DeploymentKey - DeploymentLabels []byte + DeploymentLabels json.RawMessage RunnerKey optional.Option[model.RunnerKey] Endpoint optional.Option[string] - RunnerLabels []byte + RunnerLabels pqtype.NullRawMessage } func (q *Queries) GetProcessList(ctx context.Context) ([]GetProcessListRow, error) { - rows, err := q.db.Query(ctx, getProcessList) + rows, err := q.db.QueryContext(ctx, getProcessList) if err != nil { return nil, err } @@ -1441,6 +1495,9 @@ func (q *Queries) GetProcessList(ctx context.Context) ([]GetProcessListRow, erro } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1464,13 +1521,13 @@ LIMIT 1 type GetRandomSubscriberRow struct { Sink schema.RefKey RetryAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] } func (q *Queries) GetRandomSubscriber(ctx context.Context, key model.SubscriptionKey) (GetRandomSubscriberRow, error) { - row := q.db.QueryRow(ctx, getRandomSubscriber, key) + row := q.db.QueryRowContext(ctx, getRandomSubscriber, key) var i GetRandomSubscriberRow err := row.Scan( &i.Sink, @@ -1499,7 +1556,7 @@ type GetRouteForRunnerRow struct { // Retrieve routing information for a runner. func (q *Queries) GetRouteForRunner(ctx context.Context, key model.RunnerKey) (GetRouteForRunnerRow, error) { - row := q.db.QueryRow(ctx, getRouteForRunner, key) + row := q.db.QueryRowContext(ctx, getRouteForRunner, key) var i GetRouteForRunnerRow err := row.Scan( &i.Endpoint, @@ -1528,7 +1585,7 @@ type GetRoutingTableRow struct { } func (q *Queries) GetRoutingTable(ctx context.Context, modules []string) ([]GetRoutingTableRow, error) { - rows, err := q.db.Query(ctx, getRoutingTable, modules) + rows, err := q.db.QueryContext(ctx, getRoutingTable, pq.Array(modules)) if err != nil { return nil, err } @@ -1546,6 +1603,9 @@ func (q *Queries) GetRoutingTable(ctx context.Context, modules []string) ([]GetR } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1571,14 +1631,14 @@ type GetRunnerRow struct { RunnerKey model.RunnerKey Endpoint string State RunnerState - Labels []byte + Labels json.RawMessage LastSeen time.Time ModuleName optional.Option[string] DeploymentKey optional.Option[string] } func (q *Queries) GetRunner(ctx context.Context, key model.RunnerKey) (GetRunnerRow, error) { - row := q.db.QueryRow(ctx, getRunner, key) + row := q.db.QueryRowContext(ctx, getRunner, key) var i GetRunnerRow err := row.Scan( &i.RunnerKey, @@ -1599,7 +1659,7 @@ WHERE key = $1::runner_key ` func (q *Queries) GetRunnerState(ctx context.Context, key model.RunnerKey) (RunnerState, error) { - row := q.db.QueryRow(ctx, getRunnerState, key) + row := q.db.QueryRowContext(ctx, getRunnerState, key) var state RunnerState err := row.Scan(&state) return state, err @@ -1623,18 +1683,18 @@ type GetRunnersForDeploymentRow struct { Endpoint string ModuleName optional.Option[string] DeploymentID optional.Option[int64] - Labels []byte + Labels json.RawMessage ID_2 int64 CreatedAt time.Time ModuleID int64 Key_2 model.DeploymentKey Schema *schema.Module - Labels_2 []byte + Labels_2 json.RawMessage MinReplicas int32 } func (q *Queries) GetRunnersForDeployment(ctx context.Context, key model.DeploymentKey) ([]GetRunnersForDeploymentRow, error) { - rows, err := q.db.Query(ctx, getRunnersForDeployment, key) + rows, err := q.db.QueryContext(ctx, getRunnersForDeployment, key) if err != nil { return nil, err } @@ -1665,6 +1725,9 @@ func (q *Queries) GetRunnersForDeployment(ctx context.Context, key model.Deploym } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1676,7 +1739,7 @@ SELECT schema FROM deployments WHERE key = $1::deployment_key ` func (q *Queries) GetSchemaForDeployment(ctx context.Context, key model.DeploymentKey) (*schema.Module, error) { - row := q.db.QueryRow(ctx, getSchemaForDeployment, key) + row := q.db.QueryRowContext(ctx, getSchemaForDeployment, key) var schema *schema.Module err := row.Scan(&schema) return schema, err @@ -1701,8 +1764,8 @@ type GetStaleCronJobsRow struct { State model.CronJobState } -func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) ([]GetStaleCronJobsRow, error) { - rows, err := q.db.Query(ctx, getStaleCronJobs, dollar_1) +func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 sqltypes.Duration) ([]GetStaleCronJobsRow, error) { + rows, err := q.db.QueryContext(ctx, getStaleCronJobs, dollar_1) if err != nil { return nil, err } @@ -1724,6 +1787,9 @@ func (q *Queries) GetStaleCronJobs(ctx context.Context, dollar_1 time.Duration) } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1743,7 +1809,7 @@ WHERE name = $1::TEXT ` func (q *Queries) GetSubscription(ctx context.Context, column1 string, column2 string) (TopicSubscription, error) { - row := q.db.QueryRow(ctx, getSubscription, column1, column2) + row := q.db.QueryRowContext(ctx, getSubscription, column1, column2) var i TopicSubscription err := row.Scan( &i.ID, @@ -1786,7 +1852,7 @@ type GetSubscriptionsNeedingUpdateRow struct { // Sorting ensures that brand new events (that may not be ready for consumption) // don't prevent older events from being consumed func (q *Queries) GetSubscriptionsNeedingUpdate(ctx context.Context) ([]GetSubscriptionsNeedingUpdateRow, error) { - rows, err := q.db.Query(ctx, getSubscriptionsNeedingUpdate) + rows, err := q.db.QueryContext(ctx, getSubscriptionsNeedingUpdate) if err != nil { return nil, err } @@ -1804,6 +1870,9 @@ func (q *Queries) GetSubscriptionsNeedingUpdate(ctx context.Context) ([]GetSubsc } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -1817,7 +1886,7 @@ WHERE id = $1::BIGINT ` func (q *Queries) GetTopic(ctx context.Context, dollar_1 int64) (Topic, error) { - row := q.db.QueryRow(ctx, getTopic, dollar_1) + row := q.db.QueryRowContext(ctx, getTopic, dollar_1) var i Topic err := row.Scan( &i.ID, @@ -1838,7 +1907,7 @@ WHERE id = $1::BIGINT ` func (q *Queries) GetTopicEvent(ctx context.Context, dollar_1 int64) (TopicEvent, error) { - row := q.db.QueryRow(ctx, getTopicEvent, dollar_1) + row := q.db.QueryRowContext(ctx, getTopicEvent, dollar_1) var i TopicEvent err := row.Scan( &i.ID, @@ -1899,7 +1968,7 @@ type InsertCallEventParams struct { } func (q *Queries) InsertCallEvent(ctx context.Context, arg InsertCallEventParams) error { - _, err := q.db.Exec(ctx, insertCallEvent, + _, err := q.db.ExecContext(ctx, insertCallEvent, arg.DeploymentKey, arg.RequestKey, arg.ParentRequestKey, @@ -1942,7 +2011,7 @@ type InsertDeploymentCreatedEventParams struct { } func (q *Queries) InsertDeploymentCreatedEvent(ctx context.Context, arg InsertDeploymentCreatedEventParams) error { - _, err := q.db.Exec(ctx, insertDeploymentCreatedEvent, + _, err := q.db.ExecContext(ctx, insertDeploymentCreatedEvent, arg.DeploymentKey, arg.Language, arg.ModuleName, @@ -1980,7 +2049,7 @@ type InsertDeploymentUpdatedEventParams struct { } func (q *Queries) InsertDeploymentUpdatedEvent(ctx context.Context, arg InsertDeploymentUpdatedEventParams) error { - _, err := q.db.Exec(ctx, insertDeploymentUpdatedEvent, + _, err := q.db.ExecContext(ctx, insertDeploymentUpdatedEvent, arg.DeploymentKey, arg.Language, arg.ModuleName, @@ -2010,7 +2079,7 @@ type InsertEventParams struct { } func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) error { - _, err := q.db.Exec(ctx, insertEvent, + _, err := q.db.ExecContext(ctx, insertEvent, arg.DeploymentID, arg.RequestID, arg.ParentRequestID, @@ -2057,7 +2126,7 @@ type InsertLogEventParams struct { } func (q *Queries) InsertLogEvent(ctx context.Context, arg InsertLogEventParams) error { - _, err := q.db.Exec(ctx, insertLogEvent, + _, err := q.db.ExecContext(ctx, insertLogEvent, arg.DeploymentKey, arg.RequestKey, arg.TimeStamp, @@ -2103,13 +2172,13 @@ type InsertSubscriberParams struct { Deployment model.DeploymentKey Sink schema.RefKey RetryAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] } func (q *Queries) InsertSubscriber(ctx context.Context, arg InsertSubscriberParams) error { - _, err := q.db.Exec(ctx, insertSubscriber, + _, err := q.db.ExecContext(ctx, insertSubscriber, arg.Key, arg.Module, arg.SubscriptionName, @@ -2134,8 +2203,8 @@ FROM matches ` // Mark any controller entries that haven't been updated recently as dead. -func (q *Queries) KillStaleControllers(ctx context.Context, timeout time.Duration) (int64, error) { - row := q.db.QueryRow(ctx, killStaleControllers, timeout) +func (q *Queries) KillStaleControllers(ctx context.Context, timeout sqltypes.Duration) (int64, error) { + row := q.db.QueryRowContext(ctx, killStaleControllers, timeout) var count int64 err := row.Scan(&count) return count, err @@ -2152,8 +2221,8 @@ SELECT COUNT(*) FROM matches ` -func (q *Queries) KillStaleRunners(ctx context.Context, timeout time.Duration) (int64, error) { - row := q.db.QueryRow(ctx, killStaleRunners, timeout) +func (q *Queries) KillStaleRunners(ctx context.Context, timeout sqltypes.Duration) (int64, error) { + row := q.db.QueryRowContext(ctx, killStaleRunners, timeout) var count int64 err := row.Scan(&count) return count, err @@ -2166,7 +2235,7 @@ WHERE id = $1 ` func (q *Queries) LoadAsyncCall(ctx context.Context, id int64) (AsyncCall, error) { - row := q.db.QueryRow(ctx, loadAsyncCall, id) + row := q.db.QueryRowContext(ctx, loadAsyncCall, id) var i AsyncCall err := row.Scan( &i.ID, @@ -2206,8 +2275,8 @@ VALUES ( RETURNING idempotency_key ` -func (q *Queries) NewLease(ctx context.Context, key leases.Key, ttl time.Duration, metadata []byte) (uuid.UUID, error) { - row := q.db.QueryRow(ctx, newLease, key, ttl, metadata) +func (q *Queries) NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) { + row := q.db.QueryRowContext(ctx, newLease, key, ttl, metadata) var idempotency_key uuid.UUID err := row.Scan(&idempotency_key) return idempotency_key, err @@ -2245,11 +2314,11 @@ type PublishEventForTopicParams struct { Caller string Payload []byte RequestKey string - TraceContext []byte + TraceContext json.RawMessage } func (q *Queries) PublishEventForTopic(ctx context.Context, arg PublishEventForTopicParams) error { - _, err := q.db.Exec(ctx, publishEventForTopic, + _, err := q.db.ExecContext(ctx, publishEventForTopic, arg.Key, arg.Module, arg.Topic, @@ -2268,7 +2337,7 @@ RETURNING true ` func (q *Queries) ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { - row := q.db.QueryRow(ctx, releaseLease, idempotencyKey, key) + row := q.db.QueryRowContext(ctx, releaseLease, idempotencyKey, key) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -2281,8 +2350,8 @@ WHERE idempotency_key = $2 AND key = $3::lease_key RETURNING true ` -func (q *Queries) RenewLease(ctx context.Context, ttl time.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { - row := q.db.QueryRow(ctx, renewLease, ttl, idempotencyKey, key) +func (q *Queries) RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { + row := q.db.QueryRowContext(ctx, renewLease, ttl, idempotencyKey, key) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -2307,8 +2376,8 @@ RETURNING runners.id, runners.key, runners.created, runners.last_seen, runners.r ` // Find an idle runner and reserve it for the given deployment. -func (q *Queries) ReserveRunner(ctx context.Context, reservationTimeout time.Time, deploymentKey model.DeploymentKey, labels []byte) (Runner, error) { - row := q.db.QueryRow(ctx, reserveRunner, reservationTimeout, deploymentKey, labels) +func (q *Queries) ReserveRunner(ctx context.Context, reservationTimeout time.Time, deploymentKey model.DeploymentKey, labels json.RawMessage) (Runner, error) { + row := q.db.QueryRowContext(ctx, reserveRunner, reservationTimeout, deploymentKey, labels) var i Runner err := row.Scan( &i.ID, @@ -2333,7 +2402,7 @@ RETURNING 1 ` func (q *Queries) SetDeploymentDesiredReplicas(ctx context.Context, key model.DeploymentKey, minReplicas int32) error { - _, err := q.db.Exec(ctx, setDeploymentDesiredReplicas, key, minReplicas) + _, err := q.db.ExecContext(ctx, setDeploymentDesiredReplicas, key, minReplicas) return err } @@ -2350,7 +2419,7 @@ WHERE key = $1::subscription_key ` func (q *Queries) SetSubscriptionCursor(ctx context.Context, column1 model.SubscriptionKey, column2 model.TopicEventKey) error { - _, err := q.db.Exec(ctx, setSubscriptionCursor, column1, column2) + _, err := q.db.ExecContext(ctx, setSubscriptionCursor, column1, column2) return err } @@ -2390,7 +2459,7 @@ type StartCronJobsRow struct { } func (q *Queries) StartCronJobs(ctx context.Context, keys []string) ([]StartCronJobsRow, error) { - rows, err := q.db.Query(ctx, startCronJobs, keys) + rows, err := q.db.QueryContext(ctx, startCronJobs, pq.Array(keys)) if err != nil { return nil, err } @@ -2414,6 +2483,9 @@ func (q *Queries) StartCronJobs(ctx context.Context, keys []string) ([]StartCron } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -2454,7 +2526,7 @@ type StartFSMTransitionParams struct { // // "key" is the unique identifier for the FSM execution. func (q *Queries) StartFSMTransition(ctx context.Context, arg StartFSMTransitionParams) (FsmInstance, error) { - row := q.db.QueryRow(ctx, startFSMTransition, + row := q.db.QueryRowContext(ctx, startFSMTransition, arg.Fsm, arg.Key, arg.DestinationState, @@ -2485,8 +2557,8 @@ WHERE id = $2 RETURNING true ` -func (q *Queries) SucceedAsyncCall(ctx context.Context, response []byte, iD int64) (bool, error) { - row := q.db.QueryRow(ctx, succeedAsyncCall, response, iD) +func (q *Queries) SucceedAsyncCall(ctx context.Context, response json.RawMessage, iD int64) (bool, error) { + row := q.db.QueryRowContext(ctx, succeedAsyncCall, response, iD) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -2506,7 +2578,7 @@ RETURNING true ` func (q *Queries) SucceedFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (bool, error) { - row := q.db.QueryRow(ctx, succeedFSMInstance, fsm, key) + row := q.db.QueryRowContext(ctx, succeedFSMInstance, fsm, key) var column_1 bool err := row.Scan(&column_1) return column_1, err @@ -2522,7 +2594,7 @@ RETURNING id ` func (q *Queries) UpsertController(ctx context.Context, key model.ControllerKey, endpoint string) (int64, error) { - row := q.db.QueryRow(ctx, upsertController, key, endpoint) + row := q.db.QueryRowContext(ctx, upsertController, key, endpoint) var id int64 err := row.Scan(&id) return id, err @@ -2536,7 +2608,7 @@ RETURNING id ` func (q *Queries) UpsertModule(ctx context.Context, language string, name string) (int64, error) { - row := q.db.QueryRow(ctx, upsertModule, language, name) + row := q.db.QueryRowContext(ctx, upsertModule, language, name) var id int64 err := row.Scan(&id) return id, err @@ -2571,7 +2643,7 @@ type UpsertRunnerParams struct { Key model.RunnerKey Endpoint string State RunnerState - Labels []byte + Labels json.RawMessage DeploymentKey optional.Option[model.DeploymentKey] } @@ -2581,7 +2653,7 @@ type UpsertRunnerParams struct { // there is no corresponding deployment, then the deployment ID is -1 // and the parent statement will fail due to a foreign key constraint. func (q *Queries) UpsertRunner(ctx context.Context, arg UpsertRunnerParams) (optional.Option[int64], error) { - row := q.db.QueryRow(ctx, upsertRunner, + row := q.db.QueryRowContext(ctx, upsertRunner, arg.Key, arg.Endpoint, arg.State, @@ -2640,7 +2712,7 @@ type UpsertSubscriptionRow struct { } func (q *Queries) UpsertSubscription(ctx context.Context, arg UpsertSubscriptionParams) (UpsertSubscriptionRow, error) { - row := q.db.QueryRow(ctx, upsertSubscription, + row := q.db.QueryRowContext(ctx, upsertSubscription, arg.Key, arg.TopicModule, arg.TopicName, @@ -2675,7 +2747,7 @@ type UpsertTopicParams struct { } func (q *Queries) UpsertTopic(ctx context.Context, arg UpsertTopicParams) error { - _, err := q.db.Exec(ctx, upsertTopic, + _, err := q.db.ExecContext(ctx, upsertTopic, arg.Topic, arg.Module, arg.Name, diff --git a/backend/controller/sql/sqltest/testing.go b/backend/controller/sql/sqltest/testing.go index 0202d62f88..16e36c2b96 100644 --- a/backend/controller/sql/sqltest/testing.go +++ b/backend/controller/sql/sqltest/testing.go @@ -2,13 +2,13 @@ package sqltest import ( "context" + "database/sql" "os" "path/filepath" "testing" "time" "github.com/alecthomas/assert/v2" - "github.com/jackc/pgx/v5/pgxpool" "github.com/TBD54566975/ftl/backend/controller/sql/databasetesting" "github.com/TBD54566975/ftl/internal/flock" @@ -16,7 +16,7 @@ import ( // OpenForTesting opens a database connection for testing, recreating the // database beforehand. -func OpenForTesting(ctx context.Context, t testing.TB) *pgxpool.Pool { +func OpenForTesting(ctx context.Context, t testing.TB) *sql.DB { t.Helper() // Acquire lock for this DB. lockPath := filepath.Join(os.TempDir(), "ftl-db-test.lock") diff --git a/backend/controller/sql/sqltypes/sqltypes.go b/backend/controller/sql/sqltypes/sqltypes.go new file mode 100644 index 0000000000..4fd49d120e --- /dev/null +++ b/backend/controller/sql/sqltypes/sqltypes.go @@ -0,0 +1,32 @@ +package sqltypes + +import ( + "database/sql/driver" + "fmt" + "strings" + "time" +) + +type Duration time.Duration + +func (d Duration) Value() (driver.Value, error) { + return time.Duration(d).String(), nil +} + +func (d *Duration) Scan(value interface{}) error { + switch v := value.(type) { + case string: + // Convert format of hh:mm:ss into format parseable by time.ParseDuration() + v = strings.Replace(v, ":", "h", 1) + v = strings.Replace(v, ":", "m", 1) + v += "s" + dur, err := time.ParseDuration(v) + if err != nil { + return fmt.Errorf("failed to parse duration %q: %w", v, err) + } + *d = Duration(dur) + return nil + default: + return fmt.Errorf("cannot scan duration %v", value) + } +} diff --git a/cmd/ftl-controller/main.go b/cmd/ftl-controller/main.go index 53ca9bc530..1b1ca03f38 100644 --- a/cmd/ftl-controller/main.go +++ b/cmd/ftl-controller/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "database/sql" "fmt" "os" "strconv" @@ -10,7 +11,6 @@ import ( "github.com/alecthomas/kong" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" - "github.com/jackc/pgx/v5/pgxpool" "github.com/TBD54566975/ftl" "github.com/TBD54566975/ftl/backend/controller" @@ -51,7 +51,7 @@ func main() { kctx.FatalIfErrorf(err, "failed to initialize observability") // The FTL controller currently only supports DB as a configuration provider/resolver. - conn, err := pgxpool.New(ctx, cli.ControllerConfig.DSN) + conn, err := sql.Open("pgx", cli.ControllerConfig.DSN) kctx.FatalIfErrorf(err) dal, err := dal.New(ctx, conn, encryptors) kctx.FatalIfErrorf(err) diff --git a/cmd/ftl/cmd_box_run.go b/cmd/ftl/cmd_box_run.go index 884f114e22..fee285d3df 100644 --- a/cmd/ftl/cmd_box_run.go +++ b/cmd/ftl/cmd_box_run.go @@ -2,11 +2,12 @@ package main import ( "context" + "database/sql" "fmt" "net/url" "time" - "github.com/jackc/pgx/v5/pgxpool" + _ "github.com/jackc/pgx/v5/stdlib" // pgx driver "github.com/jpillora/backoff" "golang.org/x/sync/errgroup" @@ -57,7 +58,7 @@ func (b *boxRunCmd) Run(ctx context.Context, projConfig projectconfig.Config) er } // Bring up the DB connection and DAL. - pool, err := pgxpool.New(ctx, config.DSN) + conn, err := sql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } @@ -68,7 +69,7 @@ func (b *boxRunCmd) Run(ctx context.Context, projConfig projectconfig.Config) er wg := errgroup.Group{} wg.Go(func() error { - return controller.Start(ctx, config, runnerScaling, pool, encryptors) + return controller.Start(ctx, config, runnerScaling, conn, encryptors) }) // Wait for the controller to come up. diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 2a037b3b91..cb21fadc54 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -2,6 +2,7 @@ package main import ( "context" + "database/sql" "errors" "fmt" "net" @@ -15,7 +16,7 @@ import ( "connectrpc.com/connect" "github.com/alecthomas/types/optional" - "github.com/jackc/pgx/v5/pgxpool" + _ "github.com/jackc/pgx/v5/stdlib" // pgx driver "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl" @@ -147,7 +148,7 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini controllerCtx = cf.ContextWithSecrets(controllerCtx, sm) // Bring up the DB connection and DAL. - pool, err := pgxpool.New(ctx, config.DSN) + conn, err := sql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } @@ -157,7 +158,7 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini } wg.Go(func() error { - if err := controller.Start(controllerCtx, config, runnerScaling, pool, encryptors); err != nil { + if err := controller.Start(controllerCtx, config, runnerScaling, conn, encryptors); err != nil { logger.Errorf(err, "controller%d failed: %v", i, err) return fmt.Errorf("controller%d failed: %w", i, err) } diff --git a/common/configuration/dal/dal.go b/common/configuration/dal/dal.go index b8e106e6ba..54a2db3083 100644 --- a/common/configuration/dal/dal.go +++ b/common/configuration/dal/dal.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/alecthomas/types/optional" - "github.com/jackc/pgx/v5/pgxpool" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/common/configuration/sql" @@ -16,8 +15,8 @@ type DAL struct { db sql.DBI } -func New(ctx context.Context, pool *pgxpool.Pool) (*DAL, error) { - dal := &DAL{db: sql.NewDB(pool)} +func New(ctx context.Context, conn sql.ConnI) (*DAL, error) { + dal := &DAL{db: sql.NewDB(conn)} return dal, nil } diff --git a/common/configuration/sql/db.go b/common/configuration/sql/db.go index c4b45fb311..8a1e45d051 100644 --- a/common/configuration/sql/db.go +++ b/common/configuration/sql/db.go @@ -6,15 +6,14 @@ package sql import ( "context" - - "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgconn" + "database/sql" ) type DBTX interface { - Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) - Query(context.Context, string, ...interface{}) (pgx.Rows, error) - QueryRow(context.Context, string, ...interface{}) pgx.Row + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row } func New(db DBTX) *Queries { @@ -25,7 +24,7 @@ type Queries struct { db DBTX } -func (q *Queries) WithTx(tx pgx.Tx) *Queries { +func (q *Queries) WithTx(tx *sql.Tx) *Queries { return &Queries{ db: tx, } diff --git a/common/configuration/sql/models.go b/common/configuration/sql/models.go index e67f71b017..c5bddc7eb9 100644 --- a/common/configuration/sql/models.go +++ b/common/configuration/sql/models.go @@ -11,10 +11,12 @@ import ( "time" "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" ) type AsyncCallState string @@ -376,16 +378,16 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request []byte - Response []byte + Request json.RawMessage + Response pqtype.NullRawMessage Error optional.Option[string] RemainingAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] Catching bool ParentRequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type Controller struct { @@ -415,7 +417,7 @@ type Deployment struct { ModuleID int64 Key model.DeploymentKey Schema *schema.Module - Labels []byte + Labels json.RawMessage MinReplicas int32 } @@ -467,7 +469,7 @@ type Lease struct { Key leases.Key CreatedAt time.Time ExpiresAt time.Time - Metadata []byte + Metadata pqtype.NullRawMessage } type Module struct { @@ -481,7 +483,7 @@ type ModuleConfiguration struct { CreatedAt time.Time Module optional.Option[string] Name string - Value []byte + Value json.RawMessage } type ModuleSecret struct { @@ -509,7 +511,7 @@ type Runner struct { Endpoint string ModuleName optional.Option[string] DeploymentID optional.Option[int64] - Labels []byte + Labels json.RawMessage } type Topic struct { @@ -530,7 +532,7 @@ type TopicEvent struct { Payload []byte Caller optional.Option[string] RequestKey optional.Option[string] - TraceContext []byte + TraceContext pqtype.NullRawMessage } type TopicSubscriber struct { @@ -541,8 +543,8 @@ type TopicSubscriber struct { DeploymentID int64 Sink schema.RefKey RetryAttempts int32 - Backoff time.Duration - MaxBackoff time.Duration + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration CatchVerb optional.Option[schema.RefKey] } diff --git a/common/configuration/sql/querier.go b/common/configuration/sql/querier.go index adfbe2f0b1..b3e7b22247 100644 --- a/common/configuration/sql/querier.go +++ b/common/configuration/sql/querier.go @@ -6,16 +6,17 @@ package sql import ( "context" + "encoding/json" "github.com/alecthomas/types/optional" ) type Querier interface { - GetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) ([]byte, error) + GetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) (json.RawMessage, error) GetModuleSecretURL(ctx context.Context, module optional.Option[string], name string) (string, error) ListModuleConfiguration(ctx context.Context) ([]ModuleConfiguration, error) ListModuleSecrets(ctx context.Context) ([]ModuleSecret, error) - SetModuleConfiguration(ctx context.Context, module optional.Option[string], name string, value []byte) error + SetModuleConfiguration(ctx context.Context, module optional.Option[string], name string, value json.RawMessage) error SetModuleSecretURL(ctx context.Context, module optional.Option[string], name string, url string) error UnsetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) error UnsetModuleSecret(ctx context.Context, module optional.Option[string], name string) error diff --git a/common/configuration/sql/queries.sql.go b/common/configuration/sql/queries.sql.go index f611ce598c..b20dc48fcd 100644 --- a/common/configuration/sql/queries.sql.go +++ b/common/configuration/sql/queries.sql.go @@ -7,6 +7,7 @@ package sql import ( "context" + "encoding/json" "github.com/alecthomas/types/optional" ) @@ -21,9 +22,9 @@ ORDER BY module NULLS LAST LIMIT 1 ` -func (q *Queries) GetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) ([]byte, error) { - row := q.db.QueryRow(ctx, getModuleConfiguration, module, name) - var value []byte +func (q *Queries) GetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) (json.RawMessage, error) { + row := q.db.QueryRowContext(ctx, getModuleConfiguration, module, name) + var value json.RawMessage err := row.Scan(&value) return value, err } @@ -39,7 +40,7 @@ LIMIT 1 ` func (q *Queries) GetModuleSecretURL(ctx context.Context, module optional.Option[string], name string) (string, error) { - row := q.db.QueryRow(ctx, getModuleSecretURL, module, name) + row := q.db.QueryRowContext(ctx, getModuleSecretURL, module, name) var url string err := row.Scan(&url) return url, err @@ -52,7 +53,7 @@ ORDER BY module, name ` func (q *Queries) ListModuleConfiguration(ctx context.Context) ([]ModuleConfiguration, error) { - rows, err := q.db.Query(ctx, listModuleConfiguration) + rows, err := q.db.QueryContext(ctx, listModuleConfiguration) if err != nil { return nil, err } @@ -71,6 +72,9 @@ func (q *Queries) ListModuleConfiguration(ctx context.Context) ([]ModuleConfigur } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -84,7 +88,7 @@ ORDER BY module, name ` func (q *Queries) ListModuleSecrets(ctx context.Context) ([]ModuleSecret, error) { - rows, err := q.db.Query(ctx, listModuleSecrets) + rows, err := q.db.QueryContext(ctx, listModuleSecrets) if err != nil { return nil, err } @@ -103,6 +107,9 @@ func (q *Queries) ListModuleSecrets(ctx context.Context) ([]ModuleSecret, error) } items = append(items, i) } + if err := rows.Close(); err != nil { + return nil, err + } if err := rows.Err(); err != nil { return nil, err } @@ -115,8 +122,8 @@ VALUES ($1, $2, $3) ON CONFLICT ((COALESCE(module, '')), name) DO UPDATE SET value = $3 ` -func (q *Queries) SetModuleConfiguration(ctx context.Context, module optional.Option[string], name string, value []byte) error { - _, err := q.db.Exec(ctx, setModuleConfiguration, module, name, value) +func (q *Queries) SetModuleConfiguration(ctx context.Context, module optional.Option[string], name string, value json.RawMessage) error { + _, err := q.db.ExecContext(ctx, setModuleConfiguration, module, name, value) return err } @@ -127,7 +134,7 @@ ON CONFLICT ((COALESCE(module, '')), name) DO UPDATE SET url = $3 ` func (q *Queries) SetModuleSecretURL(ctx context.Context, module optional.Option[string], name string, url string) error { - _, err := q.db.Exec(ctx, setModuleSecretURL, module, name, url) + _, err := q.db.ExecContext(ctx, setModuleSecretURL, module, name, url) return err } @@ -137,7 +144,7 @@ WHERE COALESCE(module, '') = COALESCE($1, '') AND name = $2 ` func (q *Queries) UnsetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) error { - _, err := q.db.Exec(ctx, unsetModuleConfiguration, module, name) + _, err := q.db.ExecContext(ctx, unsetModuleConfiguration, module, name) return err } @@ -147,6 +154,6 @@ WHERE COALESCE(module, '') = COALESCE($1, '') AND name = $2 ` func (q *Queries) UnsetModuleSecret(ctx context.Context, module optional.Option[string], name string) error { - _, err := q.db.Exec(ctx, unsetModuleSecret, module, name) + _, err := q.db.ExecContext(ctx, unsetModuleSecret, module, name) return err } diff --git a/go.mod b/go.mod index 494f767c52..d319ae82fe 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/radovskyb/watcher v1.0.7 github.com/rs/cors v1.11.0 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 + github.com/sqlc-dev/pqtype v0.3.0 github.com/swaggest/jsonschema-go v0.3.72 github.com/tink-crypto/tink-go/v2 v2.2.0 github.com/titanous/json5 v1.0.0 @@ -127,7 +128,7 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect - github.com/lib/pq v1.10.9 // indirect + github.com/lib/pq v1.10.9 github.com/pelletier/go-toml v1.9.5 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect diff --git a/go.sum b/go.sum index 187085ef5a..7a347a6f28 100644 --- a/go.sum +++ b/go.sum @@ -227,6 +227,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/jsonrpc2 v0.2.0 h1:KjN/dC4fP6aN9030MZCJs9WQbTOjWHhrtKVpzzSrr/U= github.com/sourcegraph/jsonrpc2 v0.2.0/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= diff --git a/sqlc.yaml b/sqlc.yaml index e234043ab6..d1794ddf46 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -12,7 +12,6 @@ sql: gen: go: &gengo package: "sql" - sql_package: "pgx/v5" out: "backend/controller/sql" emit_interface: true query_parameter_limit: 3 @@ -26,11 +25,11 @@ sql: - db_type: "timestamptz" go_type: "time.Time" - db_type: "pg_catalog.interval" - go_type: "time.Duration" + go_type: "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes.Duration" - db_type: "pg_catalog.interval" nullable: true go_type: - type: "optional.Option[time.Duration]" + type: "optional.Option[sqltypes.Duration]" - db_type: "module_schema_pb" go_type: "*github.com/TBD54566975/ftl/backend/schema.Module" - db_type: "timestamptz" From 1d4bf298dc073976fd289edd3fdcd4368a0ac01b Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Fri, 9 Aug 2024 11:44:13 +1000 Subject: [PATCH 03/35] chore: add linter for correct usage of CommitOrRollback (#2306) image --- .github/workflows/ci.yml | 2 + Justfile | 1 + backend/controller/dal/dal.go | 2 +- cmd/lint-commit-or-rollback/go.mod | 15 ++++ cmd/lint-commit-or-rollback/go.sum | 12 +++ cmd/lint-commit-or-rollback/main.go | 94 ++++++++++++++++++++ cmd/lint-commit-or-rollback/main_test.go | 25 ++++++ cmd/lint-commit-or-rollback/testdata/go.mod | 7 ++ cmd/lint-commit-or-rollback/testdata/go.sum | 34 +++++++ cmd/lint-commit-or-rollback/testdata/main.go | 70 +++++++++++++++ scripts/ftl | 2 +- scripts/lint-commit-or-rollback | 1 + 12 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 cmd/lint-commit-or-rollback/go.mod create mode 100644 cmd/lint-commit-or-rollback/go.sum create mode 100644 cmd/lint-commit-or-rollback/main.go create mode 100644 cmd/lint-commit-or-rollback/main_test.go create mode 100644 cmd/lint-commit-or-rollback/testdata/go.mod create mode 100644 cmd/lint-commit-or-rollback/testdata/go.sum create mode 100644 cmd/lint-commit-or-rollback/testdata/main.go create mode 120000 scripts/lint-commit-or-rollback diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a6e3db134..eed1614d74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,6 +89,8 @@ jobs: uses: ./.github/actions/build-cache - name: golangci-lint run: golangci-lint run --new-from-rev="$(git merge-base origin/main HEAD)" --out-format github-actions ./... + - name: lint-commit-or-rollback + run: lint-commit-or-rollback ./backend/... 2>&1 | to-annotation - name: go-check-sumtype shell: bash run: go-check-sumtype ./... 2>&1 | to-annotation diff --git a/Justfile b/Justfile index a2d09bc4e1..ebdc6a56c3 100644 --- a/Justfile +++ b/Justfile @@ -158,6 +158,7 @@ lint-frontend: build-frontend # Lint the backend lint-backend: @golangci-lint run --new-from-rev=$(git merge-base origin/main HEAD) ./... + @lint-commit-or-rollback ./backend/... lint-scripts: @shellcheck -f gcc -e SC2016 $(find scripts -type f -not -path scripts/tests) | to-annotation diff --git a/backend/controller/dal/dal.go b/backend/controller/dal/dal.go index 6a8d625750..55229c1b9c 100644 --- a/backend/controller/dal/dal.go +++ b/backend/controller/dal/dal.go @@ -684,7 +684,7 @@ func (p *postgresClaim) Rollback(ctx context.Context) error { func (p *postgresClaim) Runner() Runner { return p.runner } // SetDeploymentReplicas activates the given deployment. -func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey, minReplicas int) error { +func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey, minReplicas int) (err error) { // Start the transaction tx, err := d.db.Begin(ctx) if err != nil { diff --git a/cmd/lint-commit-or-rollback/go.mod b/cmd/lint-commit-or-rollback/go.mod new file mode 100644 index 0000000000..13c228b7a7 --- /dev/null +++ b/cmd/lint-commit-or-rollback/go.mod @@ -0,0 +1,15 @@ +module github.com/tbdeng/pfi/cmd/lint-commit-or-rollback + +go 1.22.0 + +require golang.org/x/tools v0.18.0 + +require ( + github.com/alecthomas/repr v0.4.0 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect +) + +require ( + github.com/alecthomas/assert/v2 v2.6.0 + golang.org/x/mod v0.15.0 // indirect +) diff --git a/cmd/lint-commit-or-rollback/go.sum b/cmd/lint-commit-or-rollback/go.sum new file mode 100644 index 0000000000..927131f006 --- /dev/null +++ b/cmd/lint-commit-or-rollback/go.sum @@ -0,0 +1,12 @@ +github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= +github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= diff --git a/cmd/lint-commit-or-rollback/main.go b/cmd/lint-commit-or-rollback/main.go new file mode 100644 index 0000000000..ab7dab3b11 --- /dev/null +++ b/cmd/lint-commit-or-rollback/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "go/ast" + "go/token" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/singlechecker" +) + +var Analyzer = &analysis.Analyzer{ + Name: "commitorrollback", + Doc: "Detects misues of dal.TX.CommitOrRollback", + Run: run, +} + +// Detect that any use of dal.TX.CommitOrRollback is in a defer statement and +// takes a reference to a named error return parameter. +// +// ie. Must be in the following form +// +// func myFunc() (err error) { +// // ... +// defer tx.CommitOrRollback(&err) +// } +func run(pass *analysis.Pass) (interface{}, error) { + var inspect func(n ast.Node) bool + funcStack := []*ast.FuncType{} + inspect = func(n ast.Node) bool { + switch n := n.(type) { + case nil: + return false + + case *ast.FuncLit: + funcStack = append(funcStack, n.Type) + ast.Inspect(n.Body, inspect) + funcStack = funcStack[:len(funcStack)-1] + return false + + case *ast.FuncDecl: + funcStack = append(funcStack, n.Type) + ast.Inspect(n.Body, inspect) + funcStack = funcStack[:len(funcStack)-1] + return false + + case *ast.CallExpr: + sel, ok := n.Fun.(*ast.SelectorExpr) + if !ok { + return true + } + x, ok := sel.X.(*ast.Ident) + if !ok || x.Name != "tx" || sel.Sel.Name != "CommitOrRollback" || len(n.Args) != 2 { + return true + } + arg0, ok := n.Args[1].(*ast.UnaryExpr) + if !ok || arg0.Op != token.AND { + return true + } + arg0Ident, ok := arg0.X.(*ast.Ident) + if !ok { + return true + } + funcDecl := funcStack[len(funcStack)-1] + funcPos := pass.Fset.Position(funcDecl.Func) + if funcDecl.Results == nil { + pass.Reportf(arg0.Pos(), "defer tx.CommitOrRollback(ctx, &err) should be deferred with a named error return parameter but the function at %s has no named return parameters", funcPos) + return true + } + for _, field := range funcDecl.Results.List { + if result, ok := field.Type.(*ast.Ident); ok && result.Name == "error" { + if len(field.Names) == 0 { + pass.Reportf(arg0.Pos(), "defer tx.CommitOrRollback(ctx, &err) should be deferred with a reference to a named error return parameter, but the function at %s has no named return parameters", funcPos) + } + for _, name := range field.Names { + if name.Name != arg0Ident.Name { + namePos := pass.Fset.Position(name.NamePos) + pass.Reportf(arg0.Pos(), "defer tx.CommitOrRollback(&ctx, %s) should be deferred with the named error return parameter here %s", arg0Ident.Name, namePos) + } + } + } + } + } + return true + } + for _, file := range pass.Files { + funcStack = []*ast.FuncType{} + ast.Inspect(file, inspect) + } + return nil, nil +} + +func main() { + singlechecker.Main(Analyzer) +} diff --git a/cmd/lint-commit-or-rollback/main_test.go b/cmd/lint-commit-or-rollback/main_test.go new file mode 100644 index 0000000000..430af58672 --- /dev/null +++ b/cmd/lint-commit-or-rollback/main_test.go @@ -0,0 +1,25 @@ +package main + +import ( + "os" + "os/exec" + "strings" + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestLinter(t *testing.T) { + pwd, err := os.Getwd() + assert.NoError(t, err) + cmd := exec.Command("lint-commit-or-rollback", ".") + cmd.Dir = "testdata" + output, err := cmd.CombinedOutput() + assert.Error(t, err) + expected := ` +` + pwd + `/testdata/main.go:35:29: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:29:6 has no named return parameters +` + pwd + `/testdata/main.go:44:28: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:28:1 has no named return parameters +` + pwd + `/testdata/main.go:55:29: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:49:6 has no named return parameters + ` + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(output))) +} diff --git a/cmd/lint-commit-or-rollback/testdata/go.mod b/cmd/lint-commit-or-rollback/testdata/go.mod new file mode 100644 index 0000000000..1e35d08e48 --- /dev/null +++ b/cmd/lint-commit-or-rollback/testdata/go.mod @@ -0,0 +1,7 @@ +module main + +go 1.22.2 + +replace pfi/backend => ../../../backend + +require pfi/backend v0.0.0-00010101000000-000000000000 diff --git a/cmd/lint-commit-or-rollback/testdata/go.sum b/cmd/lint-commit-or-rollback/testdata/go.sum new file mode 100644 index 0000000000..07c3ecb203 --- /dev/null +++ b/cmd/lint-commit-or-rollback/testdata/go.sum @@ -0,0 +1,34 @@ +github.com/alecthomas/assert/v2 v2.5.0 h1:OJKYg53BQx06/bMRBSPDCO49CbCDNiUQXwdoNrt6x5w= +github.com/alecthomas/assert/v2 v2.5.0/go.mod h1:fw5suVxB+wfYJ3291t0hRTqtGzFYdSwstnRQdaQx2DM= +github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8= +github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= +modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/cmd/lint-commit-or-rollback/testdata/main.go b/cmd/lint-commit-or-rollback/testdata/main.go new file mode 100644 index 0000000000..5d87b35f00 --- /dev/null +++ b/cmd/lint-commit-or-rollback/testdata/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "context" + "database/sql" + + libdal "pfi/backend/libs/dal" +) + +type Tx struct { + *libdal.Tx[Tx] + *DAL +} + +// DAL is the data access layer for the IDV module. +type DAL struct { + db libdal.Conn + *libdal.DAL[Tx] +} + +// NewDAL creates a new Data Access Layer instance. +func NewDAL(conn *sql.DB) *DAL { + return &DAL{db: conn, DAL: libdal.New(conn, func(tx *sql.Tx, t *libdal.Tx[Tx]) *Tx { + return &Tx{DAL: &DAL{db: tx, DAL: t.DAL}, Tx: t} + })} +} + +func failure() error { + _ = func() error { + dal := DAL{} + tx, err := dal.Begin(context.Background()) + if err != nil { + return err + } + defer tx.CommitOrRollback(&err) // Should error + return nil + } + + dal := DAL{} + tx, err := dal.Begin(context.Background()) + if err != nil { + return err + } + defer tx.CommitOrRollback(&err) // Should error + return nil +} + +func success() (err error) { + _ = func() error { + dal := DAL{} + tx, err := dal.Begin(context.Background()) + if err != nil { + return err + } + defer tx.CommitOrRollback(&err) // Should error + return nil + } + dal := DAL{} + tx, err := dal.Begin(context.Background()) + if err != nil { + return err + } + defer tx.CommitOrRollback(&err) // Should NOT error + return nil +} + +func main() { + _ = failure() + _ = success() +} diff --git a/scripts/ftl b/scripts/ftl index 637597aaee..7ee8566d7a 100755 --- a/scripts/ftl +++ b/scripts/ftl @@ -4,4 +4,4 @@ ftldir="$(dirname "$0")/.." name="$(basename "$0")" dest="${ftldir}/build/devel" mkdir -p "$dest" -(cd "${ftldir}" && ./bin/go build -ldflags="-s -w -buildid=" -o "$dest/${name}" "./cmd/${name}") && exec "$dest/${name}" "$@" +(cd "${ftldir}/cmd/${name}" && "${ftldir}/bin/go" build -ldflags="-s -w -buildid=" -o "$dest/${name}" ./) && exec "$dest/${name}" "$@" diff --git a/scripts/lint-commit-or-rollback b/scripts/lint-commit-or-rollback new file mode 120000 index 0000000000..1db38bf169 --- /dev/null +++ b/scripts/lint-commit-or-rollback @@ -0,0 +1 @@ +ftl \ No newline at end of file From 716e6667a1077ca9161f1a4baa62bee9534525f3 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Sun, 11 Aug 2024 13:54:39 +1000 Subject: [PATCH 04/35] feat: add support for code and SQL based database migrations (#2311) We'll need to be doing data migrations quite a bit in the near future, and while at some point we will need to do proper [zero downtime migrations](https://teamplify.com/blog/zero-downtime-DB-migrations/) with all that this entails, for now it will be more expedient to accept some downtime. With that in mind, this PR adds a function for applying a mix of SQL and code-based migrations to a database. An example of where this will be used is our encrypted table columns, which are currently JSONB with a base-64 encoded JSON envelope which we want to move to raw encrypted bytes. We might also need to re-encrypt some data with new keys soon. etc. Note: this is not hooked up to `ftl migrate` or `ftl dev`'s migration subsystems yet. --------- Co-authored-by: gak --- backend/controller/sql/migrate/migrate.go | 132 ++++++++++++++++++ .../controller/sql/migrate/migrate_test.go | 112 +++++++++++++++ .../migrate/testdata/30280101000000_init.sql | 6 + backend/controller/sql/sqltest/testing.go | 3 +- 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 backend/controller/sql/migrate/migrate.go create mode 100644 backend/controller/sql/migrate/migrate_test.go create mode 100644 backend/controller/sql/migrate/testdata/30280101000000_init.sql diff --git a/backend/controller/sql/migrate/migrate.go b/backend/controller/sql/migrate/migrate.go new file mode 100644 index 0000000000..6fc73eada2 --- /dev/null +++ b/backend/controller/sql/migrate/migrate.go @@ -0,0 +1,132 @@ +// Package migrate supports a dbmate-compatible superset of migration files. +// +// The superset is that in addition to a migration being a .sql file, it can +// also be a Go function which is called to execute the migration. +package migrate + +import ( + "context" + "database/sql" + "errors" + "fmt" + "io/fs" + "path/filepath" + "reflect" + "regexp" + "runtime" + "sort" + "time" + + "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/internal/log" +) + +var migrationFileNameRe = regexp.MustCompile(`^.*(\d{14})_(.*)\.sql$`) +var migrationFuncNameRe = regexp.MustCompile(`^.*\.Migrate(\d{14})(.*)$`) + +type Migration func(ctx context.Context, db *sql.Tx) error + +type namedMigration struct { + name string + version string + migration Migration +} + +func (m namedMigration) String() string { return m.name } + +// Migrate applies all migrations in the provided fs.FS and migrationFuncs to the provided database. +// +// Migration functions must be named in the form "MigrationYYYYMMDDHHMMSS". +func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFuncs ...Migration) error { + // Create schema_migrations table if it doesn't exist. + // This table structure is compatible with dbmate. + _, _ = db.ExecContext(ctx, `CREATE TABLE schema_migrations (version TEXT PRIMARY KEY)`) //nolint:errcheck + + sqlFiles, err := fs.Glob(migrationFiles, "*.sql") + if err != nil { + return fmt.Errorf("failed to read migration files: %w", err) + } + + migrations := make([]namedMigration, 0, len(sqlFiles)+len(migrationFuncs)) + + // Collect .sql files. + for _, sqlFile := range sqlFiles { + name := filepath.Base(sqlFile) + groups := migrationFileNameRe.FindStringSubmatch(name) + if groups == nil { + return fmt.Errorf("invalid migration file name %q, must be in the form _.sql", sqlFile) + } + version := groups[1] + migrations = append(migrations, namedMigration{name, version, func(ctx context.Context, db *sql.Tx) error { + sqlMigration, err := fs.ReadFile(migrationFiles, sqlFile) + if err != nil { + return fmt.Errorf("failed to read migration file %q: %w", sqlFile, err) + } + return migrateSQLFile(ctx, db, sqlFile, sqlMigration) + }}) + } + for _, migration := range migrationFuncs { + name, version := migrationFuncVersion(migration) + migrations = append(migrations, namedMigration{name, version, migration}) + } + sort.Slice(migrations, func(i, j int) bool { + return migrations[i].version < migrations[j].version + }) + for _, migration := range migrations { + tx, err := db.Begin() + if err != nil { + return fmt.Errorf("migration %s: failed to begin transaction: %w", migration, err) + } + err = applyMigration(ctx, tx, migration) + if err != nil { + if txerr := tx.Rollback(); txerr != nil { + return fmt.Errorf("migration %s: failed to rollback transaction: %w", migration, txerr) + } + return fmt.Errorf("migration %s: %w", migration, err) + } + err = tx.Commit() + if err != nil { + return fmt.Errorf("migration %s: failed to commit transaction: %w", migration, err) + } + } + return nil +} + +func applyMigration(ctx context.Context, tx *sql.Tx, migration namedMigration) error { + start := time.Now() + logger := log.FromContext(ctx).Scope("migrate") + _, err := tx.ExecContext(ctx, "INSERT INTO schema_migrations (version) VALUES ($1)", migration.version) + err = dal.TranslatePGError(err) + if errors.Is(err, dal.ErrConflict) { + if txerr := tx.Rollback(); txerr != nil { + return fmt.Errorf("failed to rollback transaction: %w", txerr) + } + logger.Debugf("Skipping: %s", migration) + return nil + } else if err != nil { + return fmt.Errorf("failed to insert migration: %w", err) + } + logger.Debugf("Applying: %s", migration) + if err := migration.migration(ctx, tx); err != nil { + return fmt.Errorf("migration failed: %w", err) + } + logger.Debugf("Applied: %s in %s", migration, time.Since(start)) + return nil +} + +func migrationFuncVersion(i any) (name string, version string) { + name = runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() + groups := migrationFuncNameRe.FindStringSubmatch(name) + if groups == nil { + panic(fmt.Sprintf("invalid migration name %q, must be in the form Migrate", name)) + } + return name, groups[1] +} + +func migrateSQLFile(ctx context.Context, db *sql.Tx, name string, sqlMigration []byte) error { + _, err := db.ExecContext(ctx, string(sqlMigration)) + if err != nil { + return fmt.Errorf("failed to execute migration %q: %w", name, err) + } + return nil +} diff --git a/backend/controller/sql/migrate/migrate_test.go b/backend/controller/sql/migrate/migrate_test.go new file mode 100644 index 0000000000..07eadd8f9a --- /dev/null +++ b/backend/controller/sql/migrate/migrate_test.go @@ -0,0 +1,112 @@ +package migrate + +import ( + "context" + "database/sql" + "embed" + "fmt" + "io/fs" + "strconv" + "strings" + "testing" + + "github.com/alecthomas/assert/v2" + + "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" + "github.com/TBD54566975/ftl/internal/log" +) + +func TestMigrate(t *testing.T) { + ctx := log.ContextWithNewDefaultLogger(context.Background()) + db := sqltest.OpenForTesting(ctx, t) + + mfs, err := fs.Sub(migrations, "testdata") + assert.NoError(t, err) + + err = Migrate(ctx, db, mfs, Migrate30280103221530SplitNameAge) + assert.NoError(t, err) + + rows, err := db.QueryContext(ctx, "SELECT name, age FROM test") + assert.NoError(t, err) + defer rows.Close() + type user struct { + name string + age int + } + actual := []user{} + for rows.Next() { + var u user + assert.NoError(t, rows.Scan(&u.name, &u.age)) + actual = append(actual, u) + } + expected := []user{ + {"Alice", 30}, + } + assert.Equal(t, expected, actual) +} + +//go:embed testdata +var migrations embed.FS + +func Migrate30280103221530SplitNameAge(ctx context.Context, tx *sql.Tx) error { + _, err := tx.ExecContext(ctx, ` + ALTER TABLE test + ADD COLUMN name TEXT, + ADD COLUMN age INT + `) + if err != nil { + return fmt.Errorf("failed to add columns: %w", err) + } + rows, err := tx.QueryContext(ctx, "SELECT id, name_and_age FROM test") + if err != nil { + return fmt.Errorf("failed to query test: %w", err) + } + defer rows.Close() + type userUpdate struct { + name string + age int64 + } + updates := map[int]userUpdate{} + for rows.Next() { + var id int + var name string + var age int64 + err = rows.Scan(&id, &name) + if err != nil { + return fmt.Errorf("failed to scan user: %w", err) + } + nameAge := strings.Fields(name) + name = nameAge[0] + switch len(nameAge) { + case 1: + case 2: + age, err = strconv.ParseInt(nameAge[1], 10, 64) + if err != nil { + return fmt.Errorf("failed to parse age: %w", err) + } + default: + return fmt.Errorf("invalid name %q", name) + } + // We can't update the table while iterating over it, so we store the updates in a map. + updates[id] = userUpdate{name, age} + } + if err := rows.Close(); err != nil { + return fmt.Errorf("failed to close rows: %w", err) + } + for id, update := range updates { + _, err = tx.ExecContext(ctx, "UPDATE test SET name = $1, age = $2 WHERE id = $3", update.name, update.age, id) + if err != nil { + return fmt.Errorf("failed to update user %d: %w", id, err) + } + } + _, err = tx.ExecContext(ctx, ` + ALTER TABLE test + DROP COLUMN name_and_age, + ALTER COLUMN name SET NOT NULL, + ALTER COLUMN age SET NOT NULL + `) + if err != nil { + return fmt.Errorf("failed to drop column: %w", err) + } + return nil +} diff --git a/backend/controller/sql/migrate/testdata/30280101000000_init.sql b/backend/controller/sql/migrate/testdata/30280101000000_init.sql new file mode 100644 index 0000000000..02a2a2d064 --- /dev/null +++ b/backend/controller/sql/migrate/testdata/30280101000000_init.sql @@ -0,0 +1,6 @@ +CREATE TABLE test ( + id SERIAL PRIMARY KEY, + name_and_age TEXT NOT NULL +); + +INSERT INTO test (name_and_age) VALUES ('Alice 30'); \ No newline at end of file diff --git a/backend/controller/sql/sqltest/testing.go b/backend/controller/sql/sqltest/testing.go index 16e36c2b96..a2affb00fa 100644 --- a/backend/controller/sql/sqltest/testing.go +++ b/backend/controller/sql/sqltest/testing.go @@ -20,12 +20,13 @@ func OpenForTesting(ctx context.Context, t testing.TB) *sql.DB { t.Helper() // Acquire lock for this DB. lockPath := filepath.Join(os.TempDir(), "ftl-db-test.lock") - release, err := flock.Acquire(ctx, lockPath, 10*time.Second) + release, err := flock.Acquire(ctx, lockPath, 20*time.Second) assert.NoError(t, err) t.Cleanup(func() { _ = release() }) //nolint:errcheck testDSN := "postgres://localhost:15432/ftl-test?user=postgres&password=secret&sslmode=disable" conn, err := databasetesting.CreateForDevel(ctx, testDSN, true) assert.NoError(t, err) + t.Cleanup(func() { assert.NoError(t, conn.Close()) }) return conn } From b42b52cb0a68c3de709000d38ee245da5102303e Mon Sep 17 00:00:00 2001 From: gak Date: Mon, 12 Aug 2024 09:45:14 +1000 Subject: [PATCH 05/35] wip: kms part 1, core encryption functionality and deprecations. (#2312) Related #2290 Doesn't change any functionality in the system yet. It is just a refactor and new encryption types, with tests. --------- Co-authored-by: github-actions[bot] --- backend/controller/controller.go | 3 + common/configuration/asm_test.go | 10 +- go.mod | 4 + go.sum | 29 +++ internal/encryption/encryption.go | 305 ++++++++++++++++++++++-- internal/encryption/encryption_test.go | 61 ++++- internal/encryption/integration_test.go | 49 +++- testutils/localstack.go | 19 ++ 8 files changed, 444 insertions(+), 36 deletions(-) create mode 100644 testutils/localstack.go diff --git a/backend/controller/controller.go b/backend/controller/controller.go index e347fa38d9..fa329ead78 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -85,6 +85,8 @@ func (c *CommonConfig) Validate() error { return nil } +// EncryptionKeys for the controller config. +// Deprecated: Will remove this at some stage. type EncryptionKeys struct { Logs string `name:"log-key" help:"Key for sensitive log data in internal FTL tables." env:"FTL_LOG_ENCRYPTION_KEY"` Async string `name:"async-key" help:"Key for sensitive async call data in internal FTL tables." env:"FTL_ASYNC_ENCRYPTION_KEY"` @@ -133,6 +135,7 @@ type Config struct { ModuleUpdateFrequency time.Duration `help:"Frequency to send module updates." default:"30s"` EventLogRetention *time.Duration `help:"Delete call logs after this time period. 0 to disable" env:"FTL_EVENT_LOG_RETENTION" default:"24h"` ArtefactChunkSize int `help:"Size of each chunk streamed to the client." default:"1048576"` + KMSURI *url.URL `help:"URI for KMS key e.g. aws-kms://arn:aws:kms:ap-southeast-2:12345:key/0000-1111" env:"FTL_KMS_URI"` EncryptionKeys CommonConfig } diff --git a/common/configuration/asm_test.go b/common/configuration/asm_test.go index 489b9b0f01..4baf3ae46d 100644 --- a/common/configuration/asm_test.go +++ b/common/configuration/asm_test.go @@ -12,18 +12,17 @@ import ( "sort" "testing" - "connectrpc.com/connect" "github.com/TBD54566975/ftl/backend/controller/leases" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/slices" + "github.com/TBD54566975/ftl/testutils" + "connectrpc.com/connect" "github.com/alecthomas/assert/v2" "github.com/alecthomas/types/optional" . "github.com/alecthomas/types/optional" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" ) @@ -38,10 +37,7 @@ func setUp(ctx context.Context, t *testing.T, router optional.Option[Router[Secr router = optional.Some[Router[Secrets]](ProjectConfigResolver[Secrets]{Config: projectPath}) } - cc := aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider("test", "test", "")) - cfg, err := config.LoadDefaultConfig(ctx, config.WithCredentialsProvider(cc), config.WithRegion("us-west-2")) - assert.NoError(t, err) - + cfg := testutils.NewLocalstackConfig(t, ctx) externalClient := secretsmanager.NewFromConfig(cfg, func(o *secretsmanager.Options) { o.BaseEndpoint = aws.String("http://localhost:4566") }) diff --git a/go.mod b/go.mod index d319ae82fe..a9f790bb56 100644 --- a/go.mod +++ b/go.mod @@ -18,9 +18,11 @@ require ( github.com/alecthomas/participle/v2 v2.1.1 github.com/alecthomas/types v0.16.0 github.com/amacneil/dbmate/v2 v2.19.0 + github.com/aws/aws-sdk-go v1.44.267 github.com/aws/aws-sdk-go-v2 v1.30.3 github.com/aws/aws-sdk-go-v2/config v1.27.27 github.com/aws/aws-sdk-go-v2/credentials v1.17.27 + github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.4 github.com/aws/smithy-go v1.20.3 github.com/beevik/etree v1.4.1 @@ -44,6 +46,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/sqlc-dev/pqtype v0.3.0 github.com/swaggest/jsonschema-go v0.3.72 + github.com/tink-crypto/tink-go-awskms v0.0.0-20230616072154-ba4f9f22c3e9 github.com/tink-crypto/tink-go/v2 v2.2.0 github.com/titanous/json5 v1.0.0 github.com/tliron/commonlog v0.2.17 @@ -87,6 +90,7 @@ require ( github.com/gorilla/websocket v1.5.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/iancoleman/strcase v0.3.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect diff --git a/go.sum b/go.sum index 7a347a6f28..062c7340c9 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4u github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/amacneil/dbmate/v2 v2.19.0 h1:RqqkBv6/Jbupuv8GcpBXNdRdSjocddiwmfE56Oil6YA= github.com/amacneil/dbmate/v2 v2.19.0/go.mod h1:zyIkE4QZ+C+NxX0YNDb6zYlmEzCXMU7SGyYrtAJVDEk= +github.com/aws/aws-sdk-go v1.44.267 h1:Asrp6EMqqRxZvjK0NjzkWcrOk15RnWtupuUrUuZMabk= +github.com/aws/aws-sdk-go v1.44.267/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= @@ -56,6 +58,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvG github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 h1:UPTdlTOwWUX49fVi7cymEN6hDqCwe3LNv1vi7TXUutk= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.3/go.mod h1:gjDP16zn+WWalyaUqwCCioQ8gU8lzttCCc9jYsiQI/8= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.4 h1:NgRFYyFpiMD62y4VPXh4DosPFbZd4vdMVBWKk0VmWXc= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.4/go.mod h1:TKKN7IQoM7uTnyuFm9bm9cw5P//ZYTl4m3htBWQ1G/c= github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= @@ -151,6 +155,10 @@ github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE= github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -242,6 +250,8 @@ github.com/swaggest/jsonschema-go v0.3.72 h1:IHaGlR1bdBUBPfhe4tfacN2TGAPKENEGiNy github.com/swaggest/jsonschema-go v0.3.72/go.mod h1:OrGyEoVqpfSFJ4Am4V/FQcQ3mlEC1vVeleA+5ggbVW4= github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= +github.com/tink-crypto/tink-go-awskms v0.0.0-20230616072154-ba4f9f22c3e9 h1:MoIsYvBNJd8vkKZjLYloE3OK8bfcO10cMPw/EtydMBs= +github.com/tink-crypto/tink-go-awskms v0.0.0-20230616072154-ba4f9f22c3e9/go.mod h1:TTE4PoQLsYB5jQ1kK2g7WU4wzHg0Arn1CEozIUXiGSY= github.com/tink-crypto/tink-go/v2 v2.2.0 h1:L2Da0F2Udh2agtKztdr69mV/KpnY3/lGTkMgLTVIXlA= github.com/tink-crypto/tink-go/v2 v2.2.0/go.mod h1:JJ6PomeNPF3cJpfWC0lgyTES6zpJILkAX0cJNwlS3xU= github.com/titanous/json5 v1.0.0 h1:hJf8Su1d9NuI/ffpxgxQfxh/UiBFZX7bMPid0rIL/7s= @@ -260,6 +270,7 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= @@ -293,35 +304,51 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -330,6 +357,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -347,6 +375,7 @@ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/encryption/encryption.go b/internal/encryption/encryption.go index c3abe96726..59b1366e00 100644 --- a/internal/encryption/encryption.go +++ b/internal/encryption/encryption.go @@ -7,17 +7,28 @@ import ( "io" "strings" + awsv1kms "github.com/aws/aws-sdk-go/service/kms" + "github.com/tink-crypto/tink-go-awskms/integration/awskms" + "github.com/tink-crypto/tink-go/v2/aead" + "github.com/tink-crypto/tink-go/v2/core/registry" "github.com/tink-crypto/tink-go/v2/insecurecleartextkeyset" + "github.com/tink-crypto/tink-go/v2/keyderivation" "github.com/tink-crypto/tink-go/v2/keyset" + "github.com/tink-crypto/tink-go/v2/prf" "github.com/tink-crypto/tink-go/v2/streamingaead" + "github.com/tink-crypto/tink-go/v2/testing/fakekms" "github.com/tink-crypto/tink-go/v2/tink" ) +// Encryptable is an interface for encrypting and decrypting JSON payloads. +// Deprecated: This is will be changed or removed very soon. type Encryptable interface { EncryptJSON(input any) (json.RawMessage, error) DecryptJSON(input json.RawMessage, output any) error } +// NewForKeyOrURI creates a new encryptor using the provided key or URI. +// Deprecated: This is will be changed or removed very soon. func NewForKeyOrURI(keyOrURI string) (Encryptable, error) { if len(keyOrURI) == 0 { return NoOpEncryptor{}, nil @@ -29,12 +40,13 @@ func NewForKeyOrURI(keyOrURI string) (Encryptable, error) { // Otherwise should be a URI for KMS. // aws-kms://arn:aws:kms:[region]:[account-id]:key/[key-id] } else if strings.HasPrefix(keyOrURI, "aws-kms://") { - return nil, fmt.Errorf("AWS KMS is not supported yet") + panic("not implemented") } return nil, fmt.Errorf("unsupported key or uri: %s", keyOrURI) } -// NoOpEncryptor does not encrypt and just passes the input as is. +// NoOpEncryptor does not encrypt or decrypt and just passes the input as is. +// Deprecated: This is will be changed or removed very soon. type NoOpEncryptor struct { } @@ -63,7 +75,7 @@ func NewClearTextEncryptor(key string) (Encryptable, error) { return nil, fmt.Errorf("failed to read clear text keyset: %w", err) } - encryptor, err := NewEncryptor(*keySetHandle) + encryptor, err := NewDeprecatedEncryptor(*keySetHandle) if err != nil { return nil, fmt.Errorf("failed to create clear text encryptor: %w", err) } @@ -71,9 +83,9 @@ func NewClearTextEncryptor(key string) (Encryptable, error) { return encryptor, nil } -// NewEncryptor encrypts and decrypts JSON payloads using the provided key set. +// NewDeprecatedEncryptor encrypts and decrypts JSON payloads using the provided key set. // The key set must contain a primary key that is a streaming AEAD primitive. -func NewEncryptor(keySet keyset.Handle) (Encryptable, error) { +func NewDeprecatedEncryptor(keySet keyset.Handle) (Encryptable, error) { primitive, err := streamingaead.New(&keySet) if err != nil { return nil, fmt.Errorf("failed to create primitive during encryption: %w", err) @@ -82,11 +94,15 @@ func NewEncryptor(keySet keyset.Handle) (Encryptable, error) { return Encryptor{keySetHandle: keySet, primitive: primitive}, nil } +// Encryptor uses streaming with JSON payloads. +// Deprecated: This is will be changed or removed very soon. type Encryptor struct { keySetHandle keyset.Handle primitive tink.StreamingAEAD } +// EncryptedPayload is a JSON payload that contains the encrypted data to put into the database. +// Deprecated: This is will be changed or removed very soon. type EncryptedPayload struct { Encrypted []byte `json:"encrypted"` } @@ -97,21 +113,12 @@ func (e Encryptor) EncryptJSON(input any) (json.RawMessage, error) { return nil, fmt.Errorf("failed to marshal input: %w", err) } - encryptedBuffer := &bytes.Buffer{} - msgBuffer := bytes.NewBuffer(msg) - writer, err := e.primitive.NewEncryptingWriter(encryptedBuffer, nil) + encrypted, err := encryptBytesForStreaming(e.primitive, msg) if err != nil { - return nil, fmt.Errorf("failed to create encrypting writer: %w", err) - } - - if _, err := io.Copy(writer, msgBuffer); err != nil { - return nil, fmt.Errorf("failed to copy encrypted data: %w", err) - } - if err := writer.Close(); err != nil { - return nil, fmt.Errorf("failed to close encrypted writer: %w", err) + return nil, fmt.Errorf("failed to encrypt data: %w", err) } - out, err := json.Marshal(EncryptedPayload{Encrypted: encryptedBuffer.Bytes()}) + out, err := json.Marshal(EncryptedPayload{Encrypted: encrypted}) if err != nil { return nil, fmt.Errorf("failed to marshal encrypted data: %w", err) } @@ -124,20 +131,270 @@ func (e Encryptor) DecryptJSON(input json.RawMessage, output any) error { return fmt.Errorf("failed to unmarshal encrypted payload: %w", err) } - inputBytesReader := bytes.NewReader(payload.Encrypted) - reader, err := e.primitive.NewDecryptingReader(inputBytesReader, nil) + decryptedBuffer, err := decryptBytesForStreaming(e.primitive, payload.Encrypted) + if err != nil { + return fmt.Errorf("failed to decrypt data: %w", err) + } + + if err := json.Unmarshal(decryptedBuffer, output); err != nil { + return fmt.Errorf("failed to unmarshal decrypted data: %w", err) + } + + return nil +} + +func encryptBytesForStreaming(streamingPrimitive tink.StreamingAEAD, clearText []byte) ([]byte, error) { + encryptedBuffer := &bytes.Buffer{} + msgBuffer := bytes.NewBuffer(clearText) + writer, err := streamingPrimitive.NewEncryptingWriter(encryptedBuffer, nil) if err != nil { - return fmt.Errorf("failed to create decrypting reader: %w", err) + return nil, fmt.Errorf("failed to create encrypting writer: %w", err) + } + if _, err := io.Copy(writer, msgBuffer); err != nil { + return nil, fmt.Errorf("failed to copy encrypted data: %w", err) + } + if err := writer.Close(); err != nil { + return nil, fmt.Errorf("failed to close encrypted writer: %w", err) } + return encryptedBuffer.Bytes(), nil +} + +func decryptBytesForStreaming(streamingPrimitive tink.StreamingAEAD, encrypted []byte) ([]byte, error) { + encryptedBuffer := bytes.NewReader(encrypted) decryptedBuffer := &bytes.Buffer{} + reader, err := streamingPrimitive.NewDecryptingReader(encryptedBuffer, nil) + if err != nil { + return nil, fmt.Errorf("failed to create decrypting reader: %w", err) + } if _, err := io.Copy(decryptedBuffer, reader); err != nil { - return fmt.Errorf("failed to copy decrypted data: %w", err) + return nil, fmt.Errorf("failed to copy decrypted data: %w", err) } + return decryptedBuffer.Bytes(), nil +} - if err := json.Unmarshal(decryptedBuffer.Bytes(), output); err != nil { - return fmt.Errorf("failed to unmarshal decrypted data: %w", err) +type SubKey string + +const ( + LogsSubKey SubKey = "logs" + AsyncSubKey SubKey = "async" +) + +type EncryptorNext interface { + Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) + Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) +} + +// NoOpEncryptorNext does not encrypt and just passes the input as is. +type NoOpEncryptorNext struct{} + +func (n NoOpEncryptorNext) Encrypt(_ SubKey, cleartext []byte) ([]byte, error) { + return cleartext, nil +} + +func (n NoOpEncryptorNext) Decrypt(_ SubKey, encrypted []byte) ([]byte, error) { + return encrypted, nil +} + +type PlaintextEncryptor struct { + root keyset.Handle +} + +func NewPlaintextEncryptor(key string) (*PlaintextEncryptor, error) { + handle, err := insecurecleartextkeyset.Read( + keyset.NewJSONReader(bytes.NewBufferString(key))) + if err != nil { + return nil, fmt.Errorf("failed to read clear text keyset: %w", err) } - return nil + return &PlaintextEncryptor{root: *handle}, nil +} + +func (p PlaintextEncryptor) Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) { + encrypted, err := derivedEncrypt(p.root, subKey, cleartext) + if err != nil { + return nil, fmt.Errorf("failed to encrypt with derive: %w", err) + } + + return encrypted, nil +} + +func (p PlaintextEncryptor) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) { + decrypted, err := derivedDecrypt(p.root, subKey, encrypted) + if err != nil { + return nil, fmt.Errorf("failed to decrypt with derive: %w", err) + } + + return decrypted, nil +} + +// KMSEncryptor encrypts and decrypts using a KMS key via tink. +// TODO: maybe change to DerivableEncryptor and integrate plaintext and kms encryptor. +type KMSEncryptor struct { + root keyset.Handle + kekAEAD tink.AEAD + encryptedKeyset []byte +} + +func newClientWithAEAD(uri string, kms *awsv1kms.KMS) (tink.AEAD, error) { + var client registry.KMSClient + var err error + + if strings.HasPrefix(strings.ToLower(uri), "fake-kms://") { + client, err = fakekms.NewClient(uri) + if err != nil { + return nil, fmt.Errorf("failed to create fake KMS client: %w", err) + } + + } else { + // tink does not support awsv2 yet + // https://github.com/tink-crypto/tink-go-awskms/issues/2 + var opts []awskms.ClientOption + if kms != nil { + opts = append(opts, awskms.WithKMS(kms)) + } + client, err = awskms.NewClientWithOptions(uri, opts...) + if err != nil { + return nil, fmt.Errorf("failed to create KMS client: %w", err) + } + } + + kekAEAD, err := client.GetAEAD(uri) + if err != nil { + return nil, fmt.Errorf("failed to get aead: %w", err) + } + + return kekAEAD, nil +} + +func NewKMSEncryptorGenerateKey(uri string, v1client *awsv1kms.KMS) (*KMSEncryptor, error) { + kekAEAD, err := newClientWithAEAD(uri, v1client) + if err != nil { + return nil, fmt.Errorf("failed to create KMS client: %w", err) + } + + // Create a PRF key template using HKDF-SHA256 + prfKeyTemplate := prf.HKDFSHA256PRFKeyTemplate() + + // Create an AES-256-GCM key template + aeadKeyTemplate := aead.AES256GCMKeyTemplate() + + template, err := keyderivation.CreatePRFBasedKeyTemplate(prfKeyTemplate, aeadKeyTemplate) + if err != nil { + return nil, fmt.Errorf("failed to create PRF based key template: %w", err) + } + + handle, err := keyset.NewHandle(template) + if err != nil { + return nil, fmt.Errorf("failed to create keyset handle: %w", err) + } + + // Encrypt the keyset with the KEK AEAD. + buf := new(bytes.Buffer) + writer := keyset.NewBinaryWriter(buf) + err = handle.Write(writer, kekAEAD) + if err != nil { + return nil, fmt.Errorf("failed to encrypt DEK: %w", err) + } + encryptedKeyset := buf.Bytes() + + return &KMSEncryptor{ + root: *handle, + kekAEAD: kekAEAD, + encryptedKeyset: encryptedKeyset, + }, nil +} + +func NewKMSEncryptorWithKMS(uri string, v1client *awsv1kms.KMS, encryptedKeyset []byte) (*KMSEncryptor, error) { + kekAEAD, err := newClientWithAEAD(uri, v1client) + if err != nil { + return nil, fmt.Errorf("failed to create KMS client: %w", err) + } + + reader := keyset.NewBinaryReader(bytes.NewReader(encryptedKeyset)) + handle, err := keyset.Read(reader, kekAEAD) + if err != nil { + return nil, fmt.Errorf("failed to read keyset: %w", err) + } + + return &KMSEncryptor{ + root: *handle, + kekAEAD: kekAEAD, + encryptedKeyset: encryptedKeyset, + }, nil +} + +func (k *KMSEncryptor) GetEncryptedKeyset() []byte { + return k.encryptedKeyset +} + +func deriveKeyset(root keyset.Handle, salt []byte) (*keyset.Handle, error) { + deriver, err := keyderivation.New(&root) + if err != nil { + return nil, fmt.Errorf("failed to create deriver: %w", err) + } + + derived, err := deriver.DeriveKeyset(salt) + if err != nil { + return nil, fmt.Errorf("failed to derive keyset: %w", err) + } + + return derived, nil +} + +func (k *KMSEncryptor) Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) { + encrypted, err := derivedEncrypt(k.root, subKey, cleartext) + if err != nil { + return nil, fmt.Errorf("failed to encrypt with derive: %w", err) + } + + return encrypted, nil +} + +func (k *KMSEncryptor) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) { + decrypted, err := derivedDecrypt(k.root, subKey, encrypted) + if err != nil { + return nil, fmt.Errorf("failed to decrypt with derive: %w", err) + } + + return decrypted, nil +} + +func derivedDecrypt(root keyset.Handle, subKey SubKey, encrypted []byte) ([]byte, error) { + derived, err := deriveKeyset(root, []byte(subKey)) + if err != nil { + return nil, fmt.Errorf("failed to derive keyset: %w", err) + } + + primitive, err := aead.New(derived) + if err != nil { + return nil, fmt.Errorf("failed to create primitive: %w", err) + } + + bytes, err := primitive.Decrypt(encrypted, nil) + if err != nil { + return nil, fmt.Errorf("failed to decrypt: %w", err) + } + + return bytes, nil +} + +func derivedEncrypt(root keyset.Handle, subKey SubKey, cleartext []byte) ([]byte, error) { + // TODO: Deriving might be expensive, consider caching the derived keyset. + derived, err := deriveKeyset(root, []byte(subKey)) + if err != nil { + return nil, fmt.Errorf("failed to derive keyset: %w", err) + } + + primitive, err := aead.New(derived) + if err != nil { + return nil, fmt.Errorf("failed to create primitive: %w", err) + } + + bytes, err := primitive.Encrypt(cleartext, nil) + if err != nil { + return nil, fmt.Errorf("failed to encrypt: %w", err) + } + + return bytes, nil } diff --git a/internal/encryption/encryption_test.go b/internal/encryption/encryption_test.go index ba707644c2..84542d39a9 100644 --- a/internal/encryption/encryption_test.go +++ b/internal/encryption/encryption_test.go @@ -8,7 +8,7 @@ import ( "github.com/alecthomas/assert/v2" ) -const key = `{ +const streamingKey = `{ "primaryKeyId": 1720777699, "key": [{ "keyData": { @@ -20,12 +20,12 @@ const key = `{ "keyId": 1720777699, "status": "ENABLED" }] - }` +}` -func TestNewEncryptor(t *testing.T) { +func TestDeprecatedNewEncryptor(t *testing.T) { jsonInput := "\"hello\"" - encryptor, err := NewForKeyOrURI(key) + encryptor, err := NewForKeyOrURI(streamingKey) assert.NoError(t, err) encrypted, err := encryptor.EncryptJSON(jsonInput) @@ -44,3 +44,56 @@ func TestNewEncryptor(t *testing.T) { assert.Equal(t, jsonInput, decryptedString) } + +// tinkey create-keyset --key-template HKDF_SHA256_DERIVES_AES256_GCM +const key = `{"primaryKeyId":2304101620,"key":[{"keyData":{"typeUrl":"type.googleapis.com/google.crypto.tink.PrfBasedDeriverKey","value":"El0KMXR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLmNyeXB0by50aW5rLkhrZGZQcmZLZXkSJhICCAMaIDnEx9gPgeF32LQYjFYNSZe8b9KUl41Xy6to8MqKcSjBGAEaOgo4CjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNHY21LZXkSAhAgGAE=","keyMaterialType":"SYMMETRIC"},"status":"ENABLED","keyId":2304101620,"outputPrefixType":"TINK"}]}` + +func TestPlaintextEncryptor(t *testing.T) { + encryptor, err := NewPlaintextEncryptor(key) + assert.NoError(t, err) + + encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + assert.NoError(t, err) + fmt.Printf("Encrypted: %s\n", encrypted) + + decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + assert.NoError(t, err) + fmt.Printf("Decrypted: %s\n", decrypted) + + assert.Equal(t, "hunter2", string(decrypted)) + + // Should fail to decrypt with the wrong subkey + _, err = encryptor.Decrypt(AsyncSubKey, encrypted) + assert.Error(t, err) + +} + +func TestNoOpEncryptor(t *testing.T) { + encryptor := NoOpEncryptorNext{} + + encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + assert.NoError(t, err) + + decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + assert.NoError(t, err) + + assert.Equal(t, "hunter2", string(decrypted)) +} + +func TestKMSEncryptorFakeKMS(t *testing.T) { + uri := "fake-kms://CM2b3_MDElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEIK75t5L-adlUwVhWvRuWUwYARABGM2b3_MDIAE" + + encryptor, err := NewKMSEncryptorGenerateKey(uri, nil) + assert.NoError(t, err) + + encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + assert.NoError(t, err) + + decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + assert.NoError(t, err) + assert.Equal(t, "hunter2", string(decrypted)) + + // Should fail to decrypt with the wrong subkey + _, err = encryptor.Decrypt(AsyncSubKey, encrypted) + assert.Error(t, err) +} diff --git a/internal/encryption/integration_test.go b/internal/encryption/integration_test.go index fe956e3182..bef904c8bb 100644 --- a/internal/encryption/integration_test.go +++ b/internal/encryption/integration_test.go @@ -3,15 +3,25 @@ package encryption import ( + "context" "fmt" "testing" "time" - "connectrpc.com/connect" pbconsole "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/console" in "github.com/TBD54566975/ftl/integration" + "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/slices" + "github.com/TBD54566975/ftl/testutils" + + "connectrpc.com/connect" "github.com/alecthomas/assert/v2" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kms" + awsv1 "github.com/aws/aws-sdk-go/aws" + awsv1credentials "github.com/aws/aws-sdk-go/aws/credentials" + awsv1session "github.com/aws/aws-sdk-go/aws/session" + awsv1kms "github.com/aws/aws-sdk-go/service/kms" ) func TestEncryptionForLogs(t *testing.T) { @@ -97,3 +107,40 @@ func validateAsyncCall(verb string, sensitive string) in.Action { assert.NotContains(t, string(request), sensitive, "raw request string should not be stored in the table") } } + +func TestKMSEncryptorLocalstack(t *testing.T) { + endpoint := "http://localhost:4566" + + ctx := log.ContextWithNewDefaultLogger(context.Background()) + cfg := testutils.NewLocalstackConfig(t, ctx) + v2client := kms.NewFromConfig(cfg, func(o *kms.Options) { + o.BaseEndpoint = aws.String(endpoint) + }) + createKey, err := v2client.CreateKey(ctx, &kms.CreateKeyInput{}) + assert.NoError(t, err) + uri := fmt.Sprintf("aws-kms://%s", *createKey.KeyMetadata.Arn) + fmt.Printf("URI: %s\n", uri) + + // tink does not support awsv2 yet so here be dragons + // https://github.com/tink-crypto/tink-go-awskms/issues/2 + s := awsv1session.Must(awsv1session.NewSession()) + v1client := awsv1kms.New(s, &awsv1.Config{ + Credentials: awsv1credentials.NewStaticCredentials("test", "test", ""), + Endpoint: awsv1.String(endpoint), + Region: awsv1.String("us-west-2"), + }) + + encryptor, err := NewKMSEncryptorGenerateKey(uri, v1client) + assert.NoError(t, err) + + encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + assert.NoError(t, err) + + decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + assert.NoError(t, err) + assert.Equal(t, "hunter2", string(decrypted)) + + // Should fail to decrypt with the wrong subkey + _, err = encryptor.Decrypt(AsyncSubKey, encrypted) + assert.Error(t, err) +} diff --git a/testutils/localstack.go b/testutils/localstack.go new file mode 100644 index 0000000000..e1e4d40390 --- /dev/null +++ b/testutils/localstack.go @@ -0,0 +1,19 @@ +package testutils + +import ( + "context" + "testing" + + "github.com/alecthomas/assert/v2" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" +) + +func NewLocalstackConfig(t *testing.T, ctx context.Context) aws.Config { // nolint: revive + t.Helper() + cc := aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider("test", "test", "")) + cfg, err := config.LoadDefaultConfig(ctx, config.WithCredentialsProvider(cc), config.WithRegion("us-west-2")) + assert.NoError(t, err) + return cfg +} From eb712a80fb90d27da7a84d85efdd0e939a377990 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:57:49 +0000 Subject: [PATCH 06/35] chore(deps): update all non-major dependencies (#2252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | Type | Update | |---|---|---|---|---|---|---|---| | [@codemirror/view](https://togithub.com/codemirror/view) | [`6.29.0` -> `6.30.0`](https://renovatebot.com/diffs/npm/@codemirror%2fview/6.29.0/6.30.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@codemirror%2fview/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@codemirror%2fview/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@codemirror%2fview/6.29.0/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@codemirror%2fview/6.29.0/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor | | [@storybook/addon-essentials](https://togithub.com/storybookjs/storybook/tree/next/code/addons/essentials) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/addons/essentials)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2faddon-essentials/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-essentials/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-essentials/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-essentials/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-essentials/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/addon-interactions](https://togithub.com/storybookjs/storybook/tree/next/code/addons/interactions) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/addons/interactions)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2faddon-interactions/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-interactions/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-interactions/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-interactions/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-interactions/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/addon-links](https://togithub.com/storybookjs/storybook/tree/next/code/addons/links) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/addons/links)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2faddon-links/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-links/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-links/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-links/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-links/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/addon-onboarding](https://togithub.com/storybookjs/storybook/tree/next/code/addons/onboarding) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/addons/onboarding)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2faddon-onboarding/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-onboarding/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-onboarding/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-onboarding/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-onboarding/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/addon-themes](https://togithub.com/storybookjs/storybook/tree/next/code/addons/themes) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/addons/themes)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2faddon-themes/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-themes/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-themes/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-themes/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-themes/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/blocks](https://togithub.com/storybookjs/storybook/tree/next/code/lib/blocks) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/lib/blocks)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2fblocks/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2fblocks/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2fblocks/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2fblocks/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2fblocks/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/react](https://togithub.com/storybookjs/storybook/tree/next/code/renderers/react) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/renderers/react)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2freact/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2freact/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2freact/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2freact/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2freact/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/react-vite](https://togithub.com/storybookjs/storybook/tree/next/code/frameworks/react-vite) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2freact-vite/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2freact-vite/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2freact-vite/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2freact-vite/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2freact-vite/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@storybook/test](https://togithub.com/storybookjs/storybook/tree/next/code/lib/test) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/lib/test)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/@storybook%2ftest/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2ftest/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2ftest/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2ftest/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2ftest/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@types/node](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`20.14.13` -> `20.14.14`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.13/20.14.14) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/20.14.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/20.14.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/20.14.13/20.14.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/20.14.13/20.14.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [@types/vscode](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/vscode) ([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/vscode)) | [`1.91.0` -> `1.92.0`](https://renovatebot.com/diffs/npm/@types%2fvscode/1.91.0/1.92.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fvscode/1.92.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fvscode/1.92.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fvscode/1.91.0/1.92.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fvscode/1.91.0/1.92.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor | | [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)) | [`7.17.0` -> `7.18.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/7.17.0/7.18.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2feslint-plugin/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2feslint-plugin/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2feslint-plugin/7.17.0/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2feslint-plugin/7.17.0/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor | | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`7.17.0` -> `7.18.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/7.17.0/7.18.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/7.17.0/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/7.17.0/7.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor | | [act](https://togithub.com/nektos/act) | `0.2.64` -> `0.2.65` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/act/0.2.65?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/act/0.2.65?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/act/0.2.64/0.2.65?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/act/0.2.64/0.2.65?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | patch | | [buf](https://togithub.com/bufbuild/buf) | `1.35.1` -> `1.36.0` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/buf/1.36.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/buf/1.36.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/buf/1.35.1/1.36.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/buf/1.35.1/1.36.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [clap](https://togithub.com/clap-rs/clap) | `4.5.11` -> `4.5.14` | [![age](https://developer.mend.io/api/mc/badges/age/crate/clap/4.5.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/clap/4.5.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/clap/4.5.11/4.5.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/clap/4.5.11/4.5.14?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [github.com/alecthomas/assert/v2](https://togithub.com/alecthomas/assert) | `v2.6.0` -> `v2.10.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2falecthomas%2fassert%2fv2/v2.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2falecthomas%2fassert%2fv2/v2.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2falecthomas%2fassert%2fv2/v2.6.0/v2.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2falecthomas%2fassert%2fv2/v2.6.0/v2.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | [github.com/tliron/commonlog](https://togithub.com/tliron/commonlog) | `v0.2.17` -> `v0.2.18` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2ftliron%2fcommonlog/v0.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2ftliron%2fcommonlog/v0.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2ftliron%2fcommonlog/v0.2.17/v0.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2ftliron%2fcommonlog/v0.2.17/v0.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | patch | | [github.com/tliron/kutil](https://togithub.com/tliron/kutil) | `v0.3.24` -> `v0.3.25` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2ftliron%2fkutil/v0.3.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2ftliron%2fkutil/v0.3.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2ftliron%2fkutil/v0.3.24/v0.3.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2ftliron%2fkutil/v0.3.24/v0.3.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | patch | | [go](https://togithub.com/golang/go) | `1.22.5` -> `1.22.6` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/go/1.22.6?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/go/1.22.6?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/go/1.22.5/1.22.6?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/go/1.22.5/1.22.6?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | patch | | golang.org/x/mod | `v0.19.0` -> `v0.20.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fmod/v0.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2fmod/v0.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2fmod/v0.19.0/v0.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fmod/v0.19.0/v0.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | golang.org/x/net | `v0.27.0` -> `v0.28.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fnet/v0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2fnet/v0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2fnet/v0.27.0/v0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fnet/v0.27.0/v0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | golang.org/x/sync | `v0.7.0` -> `v0.8.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fsync/v0.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2fsync/v0.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2fsync/v0.7.0/v0.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fsync/v0.7.0/v0.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | golang.org/x/sys | `v0.22.0` -> `v0.24.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fsys/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2fsys/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2fsys/v0.22.0/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fsys/v0.22.0/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | golang.org/x/term | `v0.22.0` -> `v0.23.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fterm/v0.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2fterm/v0.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2fterm/v0.22.0/v0.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fterm/v0.22.0/v0.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | golang.org/x/tools | `v0.18.0` -> `v0.24.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2ftools/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/golang.org%2fx%2ftools/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/golang.org%2fx%2ftools/v0.18.0/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2ftools/v0.18.0/v0.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | [just](https://togithub.com/casey/just) | `1.32.0` -> `1.34.0` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/just/1.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/just/1.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/just/1.32.0/1.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/just/1.32.0/1.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [k3d](https://togithub.com/rancher/k3d) | `5.7.2` -> `5.7.3` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/k3d/5.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/k3d/5.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/k3d/5.7.2/5.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/k3d/5.7.2/5.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | patch | | [kotlin](https://togithub.com/JetBrains/kotlin) | `2.0.0` -> `2.0.10` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/kotlin/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/kotlin/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/kotlin/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/kotlin/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | patch | | [lint-staged](https://togithub.com/lint-staged/lint-staged) | [`15.2.7` -> `15.2.8`](https://renovatebot.com/diffs/npm/lint-staged/15.2.7/15.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/lint-staged/15.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/lint-staged/15.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/lint-staged/15.2.7/15.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lint-staged/15.2.7/15.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | `v1.31.1` -> `v1.32.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/modernc.org%2fsqlite/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/modernc.org%2fsqlite/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/modernc.org%2fsqlite/v1.31.1/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/modernc.org%2fsqlite/v1.31.1/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | [postcss](https://postcss.org/) ([source](https://togithub.com/postcss/postcss)) | [`8.4.40` -> `8.4.41`](https://renovatebot.com/diffs/npm/postcss/8.4.40/8.4.41) | [![age](https://developer.mend.io/api/mc/badges/age/npm/postcss/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/postcss/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/postcss/8.4.40/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss/8.4.40/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | postgres | `15.7` -> `15.8` | [![age](https://developer.mend.io/api/mc/badges/age/docker/postgres/15.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/docker/postgres/15.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/docker/postgres/15.7/15.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/docker/postgres/15.7/15.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [pre-commit](https://togithub.com/pre-commit/pre-commit) | `3.7.1` -> `3.8.0` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/pre-commit/3.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/pre-commit/3.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/pre-commit/3.7.1/3.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/pre-commit/3.7.1/3.8.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [protoc](https://togithub.com/protocolbuffers/protobuf) | `27.2` -> `27.3` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/protoc/27.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/protoc/27.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/protoc/27.2/27.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/protoc/27.2/27.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [react-router-dom](https://togithub.com/remix-run/react-router) ([source](https://togithub.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)) | [`6.25.1` -> `6.26.0`](https://renovatebot.com/diffs/npm/react-router-dom/6.25.1/6.26.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/react-router-dom/6.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/react-router-dom/6.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/react-router-dom/6.25.1/6.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-router-dom/6.25.1/6.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor | | [serde](https://serde.rs) ([source](https://togithub.com/serde-rs/serde)) | `1.0.204` -> `1.0.205` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde/1.0.205?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde/1.0.205?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde/1.0.204/1.0.205?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde/1.0.204/1.0.205?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [serde_json](https://togithub.com/serde-rs/json) | `1.0.121` -> `1.0.122` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde_json/1.0.122?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde_json/1.0.122?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde_json/1.0.121/1.0.122?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde_json/1.0.121/1.0.122?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [sqlc](https://togithub.com/sqlc-dev/sqlc) | `1.26.0` -> `1.27.0` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/sqlc/1.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/sqlc/1.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/sqlc/1.26.0/1.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/sqlc/1.26.0/1.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | minor | | [storybook](https://togithub.com/storybookjs/storybook/tree/next/code/lib/cli) ([source](https://togithub.com/storybookjs/storybook/tree/HEAD/code/lib/cli)) | [`8.2.7` -> `8.2.8`](https://renovatebot.com/diffs/npm/storybook/8.2.7/8.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/storybook/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/storybook/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/storybook/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/storybook/8.2.7/8.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [tailwindcss](https://tailwindcss.com) ([source](https://togithub.com/tailwindlabs/tailwindcss)) | [`3.4.7` -> `3.4.9`](https://renovatebot.com/diffs/npm/tailwindcss/3.4.7/3.4.9) | [![age](https://developer.mend.io/api/mc/badges/age/npm/tailwindcss/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwindcss/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwindcss/3.4.7/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwindcss/3.4.7/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch | | [type-fest](https://togithub.com/sindresorhus/type-fest) | [`4.23.0` -> `4.24.0`](https://renovatebot.com/diffs/npm/type-fest/4.23.0/4.24.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/type-fest/4.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/type-fest/4.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/type-fest/4.23.0/4.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/type-fest/4.23.0/4.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor | | [vscode-languageclient](https://togithub.com/Microsoft/vscode-languageserver-node) ([source](https://togithub.com/Microsoft/vscode-languageserver-node/tree/HEAD/client)) | [`10.0.0-next.9` -> `10.0.0-next.11`](https://renovatebot.com/diffs/npm/vscode-languageclient/10.0.0-next.9/10.0.0-next.11) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vscode-languageclient/10.0.0-next.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vscode-languageclient/10.0.0-next.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vscode-languageclient/10.0.0-next.9/10.0.0-next.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vscode-languageclient/10.0.0-next.9/10.0.0-next.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch | | [yq](https://togithub.com/mikefarah/yq) | `4.44.2` -> `4.44.3` | [![age](https://developer.mend.io/api/mc/badges/age/hermit/yq/4.44.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/hermit/yq/4.44.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/hermit/yq/4.44.2/4.44.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/hermit/yq/4.44.2/4.44.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | patch | | [org.codehaus.mojo:exec-maven-plugin](https://www.mojohaus.org/exec-maven-plugin) ([source](https://togithub.com/mojohaus/exec-maven-plugin)) | `3.3.0` -> `3.4.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.codehaus.mojo:exec-maven-plugin/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.codehaus.mojo:exec-maven-plugin/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.codehaus.mojo:exec-maven-plugin/3.3.0/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.codehaus.mojo:exec-maven-plugin/3.3.0/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | build | minor | | [org.jetbrains.kotlin:kotlin-reflect](https://kotlinlang.org/) ([source](https://togithub.com/JetBrains/kotlin)) | `2.0.0` -> `2.0.10` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.jetbrains.kotlin:kotlin-reflect/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.jetbrains.kotlin:kotlin-reflect/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.jetbrains.kotlin:kotlin-reflect/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.jetbrains.kotlin:kotlin-reflect/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | compile | patch | | [io.grpc:grpc-stub](https://togithub.com/grpc/grpc-java) | `1.65.1` -> `1.66.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/io.grpc:grpc-stub/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/io.grpc:grpc-stub/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/io.grpc:grpc-stub/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/io.grpc:grpc-stub/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | compile | minor | | [io.grpc:grpc-protobuf](https://togithub.com/grpc/grpc-java) | `1.65.1` -> `1.66.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/io.grpc:grpc-protobuf/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/io.grpc:grpc-protobuf/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/io.grpc:grpc-protobuf/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/io.grpc:grpc-protobuf/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | compile | minor | | [io.grpc:grpc-netty](https://togithub.com/grpc/grpc-java) | `1.65.1` -> `1.66.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/io.grpc:grpc-netty/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/io.grpc:grpc-netty/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/io.grpc:grpc-netty/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/io.grpc:grpc-netty/1.65.1/1.66.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | compile | minor | | [org.jetbrains.kotlin:kotlin-maven-plugin](https://kotlinlang.org/) ([source](https://togithub.com/JetBrains/kotlin)) | `2.0.0` -> `2.0.10` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.jetbrains.kotlin:kotlin-maven-plugin/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.jetbrains.kotlin:kotlin-maven-plugin/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.jetbrains.kotlin:kotlin-maven-plugin/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.jetbrains.kotlin:kotlin-maven-plugin/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | build | patch | | [org.jetbrains.kotlin:kotlin-test-junit5](https://kotlinlang.org/) ([source](https://togithub.com/JetBrains/kotlin)) | `2.0.0` -> `2.0.10` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.jetbrains.kotlin:kotlin-test-junit5/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.jetbrains.kotlin:kotlin-test-junit5/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.jetbrains.kotlin:kotlin-test-junit5/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.jetbrains.kotlin:kotlin-test-junit5/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | test | patch | | [org.jetbrains.kotlin:kotlin-stdlib](https://kotlinlang.org/) ([source](https://togithub.com/JetBrains/kotlin)) | `2.0.0` -> `2.0.10` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.jetbrains.kotlin:kotlin-stdlib/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.jetbrains.kotlin:kotlin-stdlib/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.jetbrains.kotlin:kotlin-stdlib/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.jetbrains.kotlin:kotlin-stdlib/2.0.0/2.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | compile | patch | --- ### Release Notes
codemirror/view (@​codemirror/view) ### [`v6.30.0`](https://togithub.com/codemirror/view/blob/HEAD/CHANGELOG.md#6300-2024-08-05) [Compare Source](https://togithub.com/codemirror/view/compare/6.29.1...6.30.0) ##### Bug fixes Make spell check corrections work again on `EditContext`-enabled Chrome versions. ##### New features The value returned by `hoverTooltip` now has an `active` property providing the state field used to store the open tooltips. ### [`v6.29.1`](https://togithub.com/codemirror/view/blob/HEAD/CHANGELOG.md#6291-2024-07-29) [Compare Source](https://togithub.com/codemirror/view/compare/6.29.0...6.29.1) ##### Bug fixes Fix a crash on old Safari browsers that don't support `MediaQueryList.addEventListener`. Fix an issue where `EditorView.viewportLineBlocks` (and thus other things like the gutter) might be out of date after some kinds of decoration changes.
storybookjs/storybook (@​storybook/addon-essentials) ### [`v8.2.8`](https://togithub.com/storybookjs/storybook/blob/HEAD/CHANGELOG.md#828) [Compare Source](https://togithub.com/storybookjs/storybook/compare/v8.2.7...v8.2.8) - CLI: Parse more Yarn Berry errors - [#​28816](https://togithub.com/storybookjs/storybook/pull/28816), thanks [@​yannbf](https://togithub.com/yannbf)! - Fix: Invariant failed: Expected package.json#version to be defined in the "undefined" package - [#​28752](https://togithub.com/storybookjs/storybook/pull/28752), thanks [@​abcdmku](https://togithub.com/abcdmku)!
storybookjs/storybook (@​storybook/addon-onboarding) ### [`v8.2.8`](https://togithub.com/storybookjs/storybook/compare/v8.2.7...2faeae23c0d6eaf398baa61937fde38e779429c0) [Compare Source](https://togithub.com/storybookjs/storybook/compare/v8.2.7...v8.2.8)
typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin) ### [`v7.18.0`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#7180-2024-07-29) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v7.17.0...v7.18.0) ##### 🩹 Fixes - **eslint-plugin:** \[no-unnecessary-type-assertion] prevent runtime error when asserting a variable declared in default TS lib - **eslint-plugin:** \[unbound-method] report on destructuring in function parameters - **eslint-plugin:** \[no-duplicate-type-constituents] shouldn't report on error types - **eslint-plugin:** \[strict-boolean-expressions] support branded booleans ##### ❤️ Thank You - auvred - Oliver Salzburg - Vinccool96 - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v7.18.0`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#7180-2024-07-29) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v7.17.0...v7.18.0) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
nektos/act (act) ### [`v0.2.65`](https://togithub.com/nektos/act/releases/tag/v0.2.65) #### Changelog ##### Bug fixes - [`3c7eda7`](https://togithub.com/nektos/act/commit/3c7eda7) fix: docker stub and add a test for this ([#​2355](https://togithub.com/nektos/act/issues/2355)) - [`a1a96da`](https://togithub.com/nektos/act/commit/a1a96da) fix: changed location of actrc in info message ([#​2373](https://togithub.com/nektos/act/issues/2373)) - [`6de25a5`](https://togithub.com/nektos/act/commit/6de25a5) fix: make node tool non volatile ([#​2372](https://togithub.com/nektos/act/issues/2372)) - [`2ad5ff7`](https://togithub.com/nektos/act/commit/2ad5ff7) fix: add missing service container health check ([#​2354](https://togithub.com/nektos/act/issues/2354)) ##### Other - [`bda491e`](https://togithub.com/nektos/act/commit/bda491e) chore: bump VERSION to 0.2.65 - [`cd8b710`](https://togithub.com/nektos/act/commit/cd8b710) remove double negation in --help ([#​2405](https://togithub.com/nektos/act/issues/2405)) - [`a62063b`](https://togithub.com/nektos/act/commit/a62063b) Bump mergo to v1.0.0 with new module URL ([#​2403](https://togithub.com/nektos/act/issues/2403)) - [`2feff3f`](https://togithub.com/nektos/act/commit/2feff3f) build(deps): bump github.com/timshannon/bolthold to v0.0.0-20240314194003-30aac6950928 ([#​2248](https://togithub.com/nektos/act/issues/2248)) - [`570ccf3`](https://togithub.com/nektos/act/commit/570ccf3) Fix [#​2363](https://togithub.com/nektos/act/issues/2363). Add /pre- and /post-entrypoint handling ([#​2394](https://togithub.com/nektos/act/issues/2394)) - [`1d6a00c`](https://togithub.com/nektos/act/commit/1d6a00c) build(deps): bump golang.org/x/term from 0.21.0 to 0.22.0 ([#​2387](https://togithub.com/nektos/act/issues/2387)) - [`21fe901`](https://togithub.com/nektos/act/commit/21fe901) build(deps): bump github.com/adrg/xdg from 0.4.0 to 0.5.0 ([#​2398](https://togithub.com/nektos/act/issues/2398)) - [`1ac4b60`](https://togithub.com/nektos/act/commit/1ac4b60) build(deps): bump megalinter/megalinter from 7.11.1 to 7.13.0 ([#​2389](https://togithub.com/nektos/act/issues/2389))
bufbuild/buf (buf) ### [`v1.36.0`](https://togithub.com/bufbuild/buf/blob/HEAD/CHANGELOG.md#v1360---2024-08-06) - Add `--list-services` and `--list-methods` flags to `buf curl`, which trigger the command to list known services or methods in the RPC schema, instead of invoking an RPC method. - Add `clean` as a top-level option in `buf.gen.yaml`, matching the `buf generate --clean` flag. If set to true, this will delete the directories, jar files, or zip files set to `out` for each plugin. - Fix git input handling of annotated tags. - Update `buf registry login` to complete the login flow in the browser by default. This allows users to login with their browser and have the token automatically provided to the CLI. - Add `buf registry organization {create, delete, info, update}` commands to manage BSR organizations. Remove `buf beta registry organization` commands. - Add `buf registry module {create, delete, deprecate, info, undeprecate, update}` commands to manage BSR modules. Remove `buf beta registry repository` commands. - Add `buf registry label {archive, info, list, unarchive}` commands to manage BSR module labels. Remove `buf beta registry label` commands and `buf beta registry {archive, unarchive}`. - Add `buf registry commit {add-label, info, list, resolve}` to manage BSR module commits. Remove `buf beta registry commit` commands.
clap-rs/clap (clap) ### [`v4.5.14`](https://togithub.com/clap-rs/clap/blob/HEAD/CHANGELOG.md#4514---2024-08-08) [Compare Source](https://togithub.com/clap-rs/clap/compare/v4.5.13...v4.5.14) ##### Features - *(unstable-ext)* Added `Arg::add` for attaching arbitrary state, like completion hints, to `Arg` without `Arg` knowing about it ### [`v4.5.13`](https://togithub.com/clap-rs/clap/blob/HEAD/CHANGELOG.md#4513---2024-07-31) [Compare Source](https://togithub.com/clap-rs/clap/compare/v4.5.12...v4.5.13) ##### Fixes - *(derive)* Improve error message when `#[flatten]`ing an optional `#[group(skip)]` - *(help)* Properly wrap long subcommand descriptions in help ### [`v4.5.12`](https://togithub.com/clap-rs/clap/blob/HEAD/CHANGELOG.md#4512---2024-07-31) [Compare Source](https://togithub.com/clap-rs/clap/compare/v4.5.11...v4.5.12)
alecthomas/assert (github.com/alecthomas/assert/v2) ### [`v2.10.0`](https://togithub.com/alecthomas/assert/compare/v2.9.0...v2.10.0) [Compare Source](https://togithub.com/alecthomas/assert/compare/v2.9.0...v2.10.0) ### [`v2.9.0`](https://togithub.com/alecthomas/assert/compare/v2.8.1...v2.9.0) [Compare Source](https://togithub.com/alecthomas/assert/compare/v2.8.1...v2.9.0) ### [`v2.8.1`](https://togithub.com/alecthomas/assert/compare/v2.8.0...v2.8.1) [Compare Source](https://togithub.com/alecthomas/assert/compare/v2.8.0...v2.8.1) ### [`v2.8.0`](https://togithub.com/alecthomas/assert/compare/v2.7.0...v2.8.0) [Compare Source](https://togithub.com/alecthomas/assert/compare/v2.7.0...v2.8.0) ### [`v2.7.0`](https://togithub.com/alecthomas/assert/compare/v2.6.0...v2.7.0) [Compare Source](https://togithub.com/alecthomas/assert/compare/v2.6.0...v2.7.0)
tliron/commonlog (github.com/tliron/commonlog) ### [`v0.2.18`](https://togithub.com/tliron/commonlog/compare/v0.2.17...v0.2.18) [Compare Source](https://togithub.com/tliron/commonlog/compare/v0.2.17...v0.2.18)
tliron/kutil (github.com/tliron/kutil) ### [`v0.3.25`](https://togithub.com/tliron/kutil/compare/v0.3.24...v0.3.25) [Compare Source](https://togithub.com/tliron/kutil/compare/v0.3.24...v0.3.25)
golang/go (go) ### [`v1.22.6`](https://togithub.com/golang/go/compare/go1.22.5...go1.22.6)
casey/just (just) ### [`v1.34.0`](https://togithub.com/casey/just/blob/HEAD/CHANGELOG.md#1340---2024-08-02) [Compare Source](https://togithub.com/casey/just/compare/1.33.0...1.34.0) ##### Fixed - Make function paths relative to correct working directory ([#​2294](https://togithub.com/casey/just/pull/2294) by [casey](https://togithub.com/casey)) ##### Changed - Keep multi-line shebangs together ([#​2276](https://togithub.com/casey/just/pull/2276) by [vkstrm](https://togithub.com/vkstrm)) ##### Misc - Document `set working-directory` ([#​2288](https://togithub.com/casey/just/pull/2288) by [nyurik](https://togithub.com/nyurik)) - Fix readme typos ([#​2289](https://togithub.com/casey/just/pull/2289) by [casey](https://togithub.com/casey)) ### [`v1.33.0`](https://togithub.com/casey/just/blob/HEAD/CHANGELOG.md#1330---2024-07-30) [Compare Source](https://togithub.com/casey/just/compare/1.32.0...1.33.0) ##### Fixed - Use correct backtick and `shell()` expression working directory in submodules ([#​2285](https://togithub.com/casey/just/pull/2285) by [casey](https://togithub.com/casey)) ##### Added - Add `working-directory` setting ([#​2283](https://togithub.com/casey/just/pull/2283) by [nyurik](https://togithub.com/nyurik)) - Allow `[group]` attribute on submodules ([#​2263](https://togithub.com/casey/just/pull/2263) by [jmwoliver](https://togithub.com/jmwoliver)) - Allow empty `[script]` attribute and add `set script-interpreter` ([#​2264](https://togithub.com/casey/just/pull/2264) by [casey](https://togithub.com/casey)) ##### Misc - Document which attributes apply to which items ([#​2282](https://togithub.com/casey/just/pull/2282) by [casey](https://togithub.com/casey)) - Add missing productions ([#​2280](https://togithub.com/casey/just/pull/2280) by [poliorcetics](https://togithub.com/poliorcetics)) - Fix Rust 1.80.0 warnings ([#​2281](https://togithub.com/casey/just/pull/2281) by [casey](https://togithub.com/casey)) - Update softprops/action-gh-release ([#​2269](https://togithub.com/casey/just/pull/2269) by [app/dependabot](https://togithub.com/app/dependabot)) - Remove `(no group)` header before ungrouped recipes ([#​2268](https://togithub.com/casey/just/pull/2268) by [casey](https://togithub.com/casey)) - Document `script-interpreter` setting ([#​2265](https://togithub.com/casey/just/pull/2265) by [casey](https://togithub.com/casey)) - `set dotenv-path` does not override `set dotenv-filename` ([#​2262](https://togithub.com/casey/just/pull/2262) by [casey](https://togithub.com/casey))
rancher/k3d (k3d) ### [`v5.7.3`](https://togithub.com/k3d-io/k3d/releases/tag/v5.7.3) #### What's Changed - fix: busybox xargs unlinked on new k3s releases by [@​thejan2009](https://togithub.com/thejan2009) in [https://github.com/k3d-io/k3d/pull/1479](https://togithub.com/k3d-io/k3d/pull/1479) **Full Changelog**: https://github.com/k3d-io/k3d/compare/v5.7.2...v5.7.3
JetBrains/kotlin (kotlin) ### [`v2.0.10`](https://togithub.com/JetBrains/kotlin/releases/tag/v2.0.10): Kotlin 2.0.10 #### 2.0.10 ##### Apple Ecosystem - [`KT-68257`](https://youtrack.jetbrains.com/issue/KT-68257) Xcode incorrectly reuses embedAndSign framework when moving to and from 2.0.0 ##### Compiler ##### Fixes - [`KT-69876`](https://youtrack.jetbrains.com/issue/KT-69876) K2 Compile exception: Only IrBlockBody together with kotlinx serialization - [`KT-68521`](https://youtrack.jetbrains.com/issue/KT-68521) K2: Property's private setters can be bypassed when using plusAssign and minusAssign operators - [`KT-68667`](https://youtrack.jetbrains.com/issue/KT-68667) K2: Compiler hangs on mapNotNull and elvis inside lambda - [`KT-68747`](https://youtrack.jetbrains.com/issue/KT-68747) K2: Long compilation time because of constraint solving when using typealias in different modules - [`KT-68940`](https://youtrack.jetbrains.com/issue/KT-68940) K2: "IllegalArgumentException: All variables should be fixed to something" - [`KT-68797`](https://youtrack.jetbrains.com/issue/KT-68797) K2 / Native: "java.lang.IllegalStateException: FIELD" caused by enabled caching - [`KT-68362`](https://youtrack.jetbrains.com/issue/KT-68362) False-positive ABSTRACT_MEMBER_NOT_IMPLEMENTED for inheritor of java class which directly implements java.util.Map - [`KT-68449`](https://youtrack.jetbrains.com/issue/KT-68449) K2: "when" expression returns Unit - [`KT-67072`](https://youtrack.jetbrains.com/issue/KT-67072) K2: inconsistent stability of open vals on receivers of final type - [`KT-68570`](https://youtrack.jetbrains.com/issue/KT-68570) K2: "Unresolved reference" in call with lambda argument and nested lambda argument - [`KT-69159`](https://youtrack.jetbrains.com/issue/KT-69159) K2: KotlinNothingValueException in Exposed - [`KT-68623`](https://youtrack.jetbrains.com/issue/KT-68623) K2: "Only safe or null-asserted calls are allowed" on safe call - [`KT-68193`](https://youtrack.jetbrains.com/issue/KT-68193) JDK 21: new MutableList.addFirst/addLast methods allow adding nullable value for non-null types - [`KT-67804`](https://youtrack.jetbrains.com/issue/KT-67804) removeFirst and removeLast return type with Java 21 - [`KT-68727`](https://youtrack.jetbrains.com/issue/KT-68727) K2: "Null argument in ExpressionCodegen for parameter VALUE_PARAMETER" caused by an enum class with default parameter in a different module - [`KT-68383`](https://youtrack.jetbrains.com/issue/KT-68383) K2: "Argument type mismatch: actual type is 'kotlin.String', but 'T & Any' was expected." with intersection types - [`KT-68546`](https://youtrack.jetbrains.com/issue/KT-68546) K2: false-positive conflicting overloads error on inheriting generic type with inherited generic and non-generic member overloads - [`KT-68626`](https://youtrack.jetbrains.com/issue/KT-68626) K2: "Conflicting Overloads" for function if inherited from generic type - [`KT-68351`](https://youtrack.jetbrains.com/issue/KT-68351) K2: "Suspension functions can only be called within coroutine body" - [`KT-68489`](https://youtrack.jetbrains.com/issue/KT-68489) K2: WRONG_ANNOTATION_TARGET with Java and Kotlin `@Target` annotation positions - [`KT-69058`](https://youtrack.jetbrains.com/issue/KT-69058) K2: Java-defined property annotations not persisted - [`KT-64515`](https://youtrack.jetbrains.com/issue/KT-64515) K2 IDE: \[NEW_INFERENCE_ERROR] in a build.gradle.kts script while applying "jvm-test-suite" plugin and then configuring
--- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/TBD54566975/ftl). Co-authored-by: Matt Toohey --- .../console/testdata/go/console/go.mod | 13 +- .../console/testdata/go/console/go.sum | 34 +- .../cronjobs/testdata/go/cron/go.mod | 12 +- .../cronjobs/testdata/go/cron/go.sum | 28 +- backend/controller/dal/testdata/go/fsm/go.mod | 13 +- backend/controller/dal/testdata/go/fsm/go.sum | 30 +- .../dal/testdata/go/fsmretry/go.mod | 12 +- .../dal/testdata/go/fsmretry/go.sum | 28 +- .../ingress/testdata/go/httpingress/go.mod | 12 +- .../ingress/testdata/go/httpingress/go.sum | 28 +- .../leases/testdata/go/leases/go.mod | 13 +- .../leases/testdata/go/leases/go.sum | 30 +- .../pubsub/testdata/go/publisher/go.mod | 12 +- .../pubsub/testdata/go/publisher/go.sum | 28 +- .../pubsub/testdata/go/subscriber/go.mod | 12 +- .../pubsub/testdata/go/subscriber/go.sum | 28 +- .../sql/testdata/go/database/go.mod | 13 +- .../sql/testdata/go/database/go.sum | 30 +- bin/{.act-0.2.64.pkg => .act-0.2.65.pkg} | 0 bin/{.buf-1.35.1.pkg => .buf-1.36.0.pkg} | 0 bin/{.go-1.22.5.pkg => .go-1.22.6.pkg} | 0 bin/{.just-1.32.0.pkg => .just-1.34.0.pkg} | 0 bin/{.k3d-5.7.2.pkg => .k3d-5.7.3.pkg} | 0 bin/{.kotlin-2.0.0.pkg => .kotlin-2.0.10.pkg} | 0 ...commit-3.7.1.pkg => .pre-commit-3.8.0.pkg} | 0 bin/{.protoc-27.2.pkg => .protoc-27.3.pkg} | 0 bin/{.sqlc-1.26.0.pkg => .sqlc-1.27.0.pkg} | 0 bin/{.yq-4.44.2.pkg => .yq-4.44.3.pkg} | 0 bin/act | 2 +- bin/buf | 2 +- bin/go | 2 +- bin/gofmt | 2 +- bin/just | 2 +- bin/k3d | 2 +- bin/kapt | 2 +- bin/kotlin | 2 +- bin/kotlin-dce-js | 2 +- bin/kotlinc-js | 2 +- bin/kotlinc-jvm | 2 +- bin/pre-commit | 2 +- bin/protoc | 2 +- bin/protoc-gen-buf-breaking | 2 +- bin/protoc-gen-buf-lint | 2 +- bin/sqlc | 2 +- bin/yq | 2 +- buildengine/testdata/alpha/go.mod | 12 +- buildengine/testdata/alpha/go.sum | 28 +- buildengine/testdata/another/go.mod | 12 +- buildengine/testdata/another/go.sum | 28 +- buildengine/testdata/echokotlin/pom.xml | 2 +- buildengine/testdata/externalkotlin/pom.xml | 2 +- buildengine/testdata/other/go.mod | 12 +- buildengine/testdata/other/go.sum | 28 +- cmd/ftl/testdata/go/echo/go.mod | 12 +- cmd/ftl/testdata/go/echo/go.sum | 28 +- cmd/ftl/testdata/go/time/go.mod | 42 ++ cmd/ftl/testdata/go/time/go.sum | 148 ++++ cmd/lint-commit-or-rollback/go.mod | 7 +- cmd/lint-commit-or-rollback/go.sum | 18 +- common/projectconfig/testdata/go/echo/go.mod | 12 +- common/projectconfig/testdata/go/echo/go.sum | 28 +- .../testdata/go/findconfig/go.mod | 12 +- .../testdata/go/findconfig/go.sum | 28 +- .../testdata/go/validateconfig/go.mod | 12 +- .../testdata/go/validateconfig/go.sum | 28 +- docker-compose.yml | 2 +- examples/go/echo/go.mod | 12 +- examples/go/echo/go.sum | 28 +- extensions/vscode/package-lock.json | 119 ++-- frontend/package-lock.json | 632 ++++++++++-------- frontend/package.json | 6 +- go-runtime/compile/testdata/go/echo/go.mod | 12 +- go-runtime/compile/testdata/go/echo/go.sum | 28 +- .../testdata/go/notexportedverb/go.mod | 12 +- .../testdata/go/notexportedverb/go.sum | 28 +- go-runtime/compile/testdata/go/one/go.mod | 20 +- go-runtime/compile/testdata/go/one/go.sum | 48 +- go-runtime/compile/testdata/go/two/go.mod | 20 +- go-runtime/compile/testdata/go/two/go.sum | 48 +- .../compile/testdata/go/undefinedverb/go.mod | 12 +- .../compile/testdata/go/undefinedverb/go.sum | 28 +- .../encoding/testdata/go/omitempty/go.mod | 12 +- .../encoding/testdata/go/omitempty/go.sum | 28 +- .../ftl/ftltest/testdata/go/outer/go.sum | 28 +- .../ftl/ftltest/testdata/go/pubsub/go.mod | 13 +- .../ftl/ftltest/testdata/go/pubsub/go.sum | 30 +- .../ftl/ftltest/testdata/go/subscriber/go.mod | 13 +- .../ftl/ftltest/testdata/go/subscriber/go.sum | 30 +- .../ftl/ftltest/testdata/go/verbtypes/go.mod | 13 +- .../ftl/ftltest/testdata/go/verbtypes/go.sum | 30 +- .../ftl/ftltest/testdata/go/wrapped/go.mod | 13 +- .../ftl/ftltest/testdata/go/wrapped/go.sum | 30 +- .../testdata/go/runtimereflection/go.mod | 12 +- .../testdata/go/runtimereflection/go.sum | 28 +- go-runtime/ftl/testdata/go/echo/go.mod | 12 +- go-runtime/ftl/testdata/go/echo/go.sum | 28 +- go-runtime/ftl/testdata/go/mapper/go.mod | 13 +- go-runtime/ftl/testdata/go/mapper/go.sum | 30 +- .../ftl/testdata/go/typeregistry/go.mod | 13 +- .../ftl/testdata/go/typeregistry/go.sum | 30 +- go-runtime/internal/testdata/go/mapper/go.mod | 12 +- go-runtime/internal/testdata/go/mapper/go.sum | 28 +- .../bin/{.go-1.22.5.pkg => .go-1.22.6.pkg} | 0 go-runtime/scaffolding/bin/go | 2 +- go-runtime/scaffolding/bin/gofmt | 2 +- go-runtime/schema/testdata/failing/go.mod | 12 +- go-runtime/schema/testdata/failing/go.sum | 28 +- go-runtime/schema/testdata/fsm/go.mod | 12 +- go-runtime/schema/testdata/fsm/go.sum | 28 +- go-runtime/schema/testdata/one/go.mod | 12 +- go-runtime/schema/testdata/one/go.sum | 28 +- go-runtime/schema/testdata/parent/go.mod | 12 +- go-runtime/schema/testdata/parent/go.sum | 28 +- go-runtime/schema/testdata/pubsub/go.mod | 12 +- go-runtime/schema/testdata/pubsub/go.sum | 28 +- go-runtime/schema/testdata/subscriber/go.mod | 12 +- go-runtime/schema/testdata/subscriber/go.sum | 28 +- go-runtime/schema/testdata/two/go.mod | 12 +- go-runtime/schema/testdata/two/go.sum | 28 +- go-runtime/schema/testdata/validation/go.mod | 12 +- go-runtime/schema/testdata/validation/go.sum | 28 +- go.mod | 20 +- go.sum | 40 +- .../encryption/testdata/go/encryption/go.mod | 12 +- .../encryption/testdata/go/encryption/go.sum | 28 +- kotlin-runtime/ftl-runtime/pom.xml | 8 +- .../scaffolding/{{ .Name | lower }}/pom.xml | 2 +- rust-runtime/Cargo.lock | 28 +- 128 files changed, 1594 insertions(+), 1278 deletions(-) rename bin/{.act-0.2.64.pkg => .act-0.2.65.pkg} (100%) rename bin/{.buf-1.35.1.pkg => .buf-1.36.0.pkg} (100%) rename bin/{.go-1.22.5.pkg => .go-1.22.6.pkg} (100%) rename bin/{.just-1.32.0.pkg => .just-1.34.0.pkg} (100%) rename bin/{.k3d-5.7.2.pkg => .k3d-5.7.3.pkg} (100%) rename bin/{.kotlin-2.0.0.pkg => .kotlin-2.0.10.pkg} (100%) rename bin/{.pre-commit-3.7.1.pkg => .pre-commit-3.8.0.pkg} (100%) rename bin/{.protoc-27.2.pkg => .protoc-27.3.pkg} (100%) rename bin/{.sqlc-1.26.0.pkg => .sqlc-1.27.0.pkg} (100%) rename bin/{.yq-4.44.2.pkg => .yq-4.44.3.pkg} (100%) rename go-runtime/scaffolding/bin/{.go-1.22.5.pkg => .go-1.22.6.pkg} (100%) diff --git a/backend/controller/console/testdata/go/console/go.mod b/backend/controller/console/testdata/go/console/go.mod index 467d787aa7..39b93f7a22 100644 --- a/backend/controller/console/testdata/go/console/go.mod +++ b/backend/controller/console/testdata/go/console/go.mod @@ -7,6 +7,7 @@ require github.com/TBD54566975/ftl v0.189.0 require ( connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect + connectrpc.com/otelconnect v0.7.1 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect @@ -33,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/console/testdata/go/console/go.sum b/backend/controller/console/testdata/go/console/go.sum index fbefaba633..9fbb9ebc36 100644 --- a/backend/controller/console/testdata/go/console/go.sum +++ b/backend/controller/console/testdata/go/console/go.sum @@ -2,6 +2,8 @@ connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE= connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc= connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U= connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= +connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= +connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= @@ -103,23 +105,27 @@ go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -134,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/cronjobs/testdata/go/cron/go.mod b/backend/controller/cronjobs/testdata/go/cron/go.mod index d7700833c2..8668d5c713 100644 --- a/backend/controller/cronjobs/testdata/go/cron/go.mod +++ b/backend/controller/cronjobs/testdata/go/cron/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/cronjobs/testdata/go/cron/go.sum b/backend/controller/cronjobs/testdata/go/cron/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/backend/controller/cronjobs/testdata/go/cron/go.sum +++ b/backend/controller/cronjobs/testdata/go/cron/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/dal/testdata/go/fsm/go.mod b/backend/controller/dal/testdata/go/fsm/go.mod index f56c99aee7..3242beebbb 100644 --- a/backend/controller/dal/testdata/go/fsm/go.mod +++ b/backend/controller/dal/testdata/go/fsm/go.mod @@ -44,19 +44,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/dal/testdata/go/fsm/go.sum b/backend/controller/dal/testdata/go/fsm/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/backend/controller/dal/testdata/go/fsm/go.sum +++ b/backend/controller/dal/testdata/go/fsm/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/dal/testdata/go/fsmretry/go.mod b/backend/controller/dal/testdata/go/fsmretry/go.mod index 2cc9c7bc6a..8d4e381536 100644 --- a/backend/controller/dal/testdata/go/fsmretry/go.mod +++ b/backend/controller/dal/testdata/go/fsmretry/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/dal/testdata/go/fsmretry/go.sum b/backend/controller/dal/testdata/go/fsmretry/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/backend/controller/dal/testdata/go/fsmretry/go.sum +++ b/backend/controller/dal/testdata/go/fsmretry/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/ingress/testdata/go/httpingress/go.mod b/backend/controller/ingress/testdata/go/httpingress/go.mod index 0e4c18a6c7..0b01b36277 100644 --- a/backend/controller/ingress/testdata/go/httpingress/go.mod +++ b/backend/controller/ingress/testdata/go/httpingress/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/ingress/testdata/go/httpingress/go.sum b/backend/controller/ingress/testdata/go/httpingress/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/backend/controller/ingress/testdata/go/httpingress/go.sum +++ b/backend/controller/ingress/testdata/go/httpingress/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/leases/testdata/go/leases/go.mod b/backend/controller/leases/testdata/go/leases/go.mod index 46a9d65323..50739f8650 100644 --- a/backend/controller/leases/testdata/go/leases/go.mod +++ b/backend/controller/leases/testdata/go/leases/go.mod @@ -7,7 +7,7 @@ replace github.com/TBD54566975/ftl => ./../../../../../.. require ( github.com/TBD54566975/ftl v0.0.0-00010101000000-000000000000 github.com/alecthomas/assert/v2 v2.10.0 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.8.0 ) require ( @@ -45,17 +45,18 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/leases/testdata/go/leases/go.sum b/backend/controller/leases/testdata/go/leases/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/backend/controller/leases/testdata/go/leases/go.sum +++ b/backend/controller/leases/testdata/go/leases/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/pubsub/testdata/go/publisher/go.mod b/backend/controller/pubsub/testdata/go/publisher/go.mod index 08ca162da5..e9df110a1f 100644 --- a/backend/controller/pubsub/testdata/go/publisher/go.mod +++ b/backend/controller/pubsub/testdata/go/publisher/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/pubsub/testdata/go/publisher/go.sum b/backend/controller/pubsub/testdata/go/publisher/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/backend/controller/pubsub/testdata/go/publisher/go.sum +++ b/backend/controller/pubsub/testdata/go/publisher/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/pubsub/testdata/go/subscriber/go.mod b/backend/controller/pubsub/testdata/go/subscriber/go.mod index d77cc53f8a..0d558421b0 100644 --- a/backend/controller/pubsub/testdata/go/subscriber/go.mod +++ b/backend/controller/pubsub/testdata/go/subscriber/go.mod @@ -38,13 +38,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/pubsub/testdata/go/subscriber/go.sum b/backend/controller/pubsub/testdata/go/subscriber/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/backend/controller/pubsub/testdata/go/subscriber/go.sum +++ b/backend/controller/pubsub/testdata/go/subscriber/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/backend/controller/sql/testdata/go/database/go.mod b/backend/controller/sql/testdata/go/database/go.mod index dcf1bb9920..46957abc44 100644 --- a/backend/controller/sql/testdata/go/database/go.mod +++ b/backend/controller/sql/testdata/go/database/go.mod @@ -42,19 +42,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/backend/controller/sql/testdata/go/database/go.sum b/backend/controller/sql/testdata/go/database/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/backend/controller/sql/testdata/go/database/go.sum +++ b/backend/controller/sql/testdata/go/database/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/bin/.act-0.2.64.pkg b/bin/.act-0.2.65.pkg similarity index 100% rename from bin/.act-0.2.64.pkg rename to bin/.act-0.2.65.pkg diff --git a/bin/.buf-1.35.1.pkg b/bin/.buf-1.36.0.pkg similarity index 100% rename from bin/.buf-1.35.1.pkg rename to bin/.buf-1.36.0.pkg diff --git a/bin/.go-1.22.5.pkg b/bin/.go-1.22.6.pkg similarity index 100% rename from bin/.go-1.22.5.pkg rename to bin/.go-1.22.6.pkg diff --git a/bin/.just-1.32.0.pkg b/bin/.just-1.34.0.pkg similarity index 100% rename from bin/.just-1.32.0.pkg rename to bin/.just-1.34.0.pkg diff --git a/bin/.k3d-5.7.2.pkg b/bin/.k3d-5.7.3.pkg similarity index 100% rename from bin/.k3d-5.7.2.pkg rename to bin/.k3d-5.7.3.pkg diff --git a/bin/.kotlin-2.0.0.pkg b/bin/.kotlin-2.0.10.pkg similarity index 100% rename from bin/.kotlin-2.0.0.pkg rename to bin/.kotlin-2.0.10.pkg diff --git a/bin/.pre-commit-3.7.1.pkg b/bin/.pre-commit-3.8.0.pkg similarity index 100% rename from bin/.pre-commit-3.7.1.pkg rename to bin/.pre-commit-3.8.0.pkg diff --git a/bin/.protoc-27.2.pkg b/bin/.protoc-27.3.pkg similarity index 100% rename from bin/.protoc-27.2.pkg rename to bin/.protoc-27.3.pkg diff --git a/bin/.sqlc-1.26.0.pkg b/bin/.sqlc-1.27.0.pkg similarity index 100% rename from bin/.sqlc-1.26.0.pkg rename to bin/.sqlc-1.27.0.pkg diff --git a/bin/.yq-4.44.2.pkg b/bin/.yq-4.44.3.pkg similarity index 100% rename from bin/.yq-4.44.2.pkg rename to bin/.yq-4.44.3.pkg diff --git a/bin/act b/bin/act index 27148c2126..c6d9c6303e 120000 --- a/bin/act +++ b/bin/act @@ -1 +1 @@ -.act-0.2.64.pkg \ No newline at end of file +.act-0.2.65.pkg \ No newline at end of file diff --git a/bin/buf b/bin/buf index 5324fa3114..578de2e3be 120000 --- a/bin/buf +++ b/bin/buf @@ -1 +1 @@ -.buf-1.35.1.pkg \ No newline at end of file +.buf-1.36.0.pkg \ No newline at end of file diff --git a/bin/go b/bin/go index 5c26cb9eda..fec23e291d 120000 --- a/bin/go +++ b/bin/go @@ -1 +1 @@ -.go-1.22.5.pkg \ No newline at end of file +.go-1.22.6.pkg \ No newline at end of file diff --git a/bin/gofmt b/bin/gofmt index 5c26cb9eda..fec23e291d 120000 --- a/bin/gofmt +++ b/bin/gofmt @@ -1 +1 @@ -.go-1.22.5.pkg \ No newline at end of file +.go-1.22.6.pkg \ No newline at end of file diff --git a/bin/just b/bin/just index 681ed58773..bf5e8a7ce2 120000 --- a/bin/just +++ b/bin/just @@ -1 +1 @@ -.just-1.32.0.pkg \ No newline at end of file +.just-1.34.0.pkg \ No newline at end of file diff --git a/bin/k3d b/bin/k3d index 5a8dc5fc0d..e5d6063fc8 120000 --- a/bin/k3d +++ b/bin/k3d @@ -1 +1 @@ -.k3d-5.7.2.pkg \ No newline at end of file +.k3d-5.7.3.pkg \ No newline at end of file diff --git a/bin/kapt b/bin/kapt index c3a07a1884..863697944d 120000 --- a/bin/kapt +++ b/bin/kapt @@ -1 +1 @@ -.kotlin-2.0.0.pkg \ No newline at end of file +.kotlin-2.0.10.pkg \ No newline at end of file diff --git a/bin/kotlin b/bin/kotlin index c3a07a1884..863697944d 120000 --- a/bin/kotlin +++ b/bin/kotlin @@ -1 +1 @@ -.kotlin-2.0.0.pkg \ No newline at end of file +.kotlin-2.0.10.pkg \ No newline at end of file diff --git a/bin/kotlin-dce-js b/bin/kotlin-dce-js index c3a07a1884..863697944d 120000 --- a/bin/kotlin-dce-js +++ b/bin/kotlin-dce-js @@ -1 +1 @@ -.kotlin-2.0.0.pkg \ No newline at end of file +.kotlin-2.0.10.pkg \ No newline at end of file diff --git a/bin/kotlinc-js b/bin/kotlinc-js index c3a07a1884..863697944d 120000 --- a/bin/kotlinc-js +++ b/bin/kotlinc-js @@ -1 +1 @@ -.kotlin-2.0.0.pkg \ No newline at end of file +.kotlin-2.0.10.pkg \ No newline at end of file diff --git a/bin/kotlinc-jvm b/bin/kotlinc-jvm index c3a07a1884..863697944d 120000 --- a/bin/kotlinc-jvm +++ b/bin/kotlinc-jvm @@ -1 +1 @@ -.kotlin-2.0.0.pkg \ No newline at end of file +.kotlin-2.0.10.pkg \ No newline at end of file diff --git a/bin/pre-commit b/bin/pre-commit index 47a53ea153..f942433653 120000 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -1 +1 @@ -.pre-commit-3.7.1.pkg \ No newline at end of file +.pre-commit-3.8.0.pkg \ No newline at end of file diff --git a/bin/protoc b/bin/protoc index 72f813a0d0..0182c62110 120000 --- a/bin/protoc +++ b/bin/protoc @@ -1 +1 @@ -.protoc-27.2.pkg \ No newline at end of file +.protoc-27.3.pkg \ No newline at end of file diff --git a/bin/protoc-gen-buf-breaking b/bin/protoc-gen-buf-breaking index 5324fa3114..578de2e3be 120000 --- a/bin/protoc-gen-buf-breaking +++ b/bin/protoc-gen-buf-breaking @@ -1 +1 @@ -.buf-1.35.1.pkg \ No newline at end of file +.buf-1.36.0.pkg \ No newline at end of file diff --git a/bin/protoc-gen-buf-lint b/bin/protoc-gen-buf-lint index 5324fa3114..578de2e3be 120000 --- a/bin/protoc-gen-buf-lint +++ b/bin/protoc-gen-buf-lint @@ -1 +1 @@ -.buf-1.35.1.pkg \ No newline at end of file +.buf-1.36.0.pkg \ No newline at end of file diff --git a/bin/sqlc b/bin/sqlc index 355549249e..2346bedaf1 120000 --- a/bin/sqlc +++ b/bin/sqlc @@ -1 +1 @@ -.sqlc-1.26.0.pkg \ No newline at end of file +.sqlc-1.27.0.pkg \ No newline at end of file diff --git a/bin/yq b/bin/yq index 8b69e6dea6..e7f0a63c8e 120000 --- a/bin/yq +++ b/bin/yq @@ -1 +1 @@ -.yq-4.44.2.pkg \ No newline at end of file +.yq-4.44.3.pkg \ No newline at end of file diff --git a/buildengine/testdata/alpha/go.mod b/buildengine/testdata/alpha/go.mod index cf678d0394..d12184a069 100644 --- a/buildengine/testdata/alpha/go.mod +++ b/buildengine/testdata/alpha/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/buildengine/testdata/alpha/go.sum b/buildengine/testdata/alpha/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/buildengine/testdata/alpha/go.sum +++ b/buildengine/testdata/alpha/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/buildengine/testdata/another/go.mod b/buildengine/testdata/another/go.mod index 3733382e1a..4924aab959 100644 --- a/buildengine/testdata/another/go.mod +++ b/buildengine/testdata/another/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/buildengine/testdata/another/go.sum b/buildengine/testdata/another/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/buildengine/testdata/another/go.sum +++ b/buildengine/testdata/another/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/buildengine/testdata/echokotlin/pom.xml b/buildengine/testdata/echokotlin/pom.xml index 5b541258e1..edabd9c0c0 100644 --- a/buildengine/testdata/echokotlin/pom.xml +++ b/buildengine/testdata/echokotlin/pom.xml @@ -9,7 +9,7 @@ 1.0-SNAPSHOT 1.8 - 2.0.0 + 2.0.10 true ${java.version} ${java.version} diff --git a/buildengine/testdata/externalkotlin/pom.xml b/buildengine/testdata/externalkotlin/pom.xml index feedfac278..33f05ecccc 100644 --- a/buildengine/testdata/externalkotlin/pom.xml +++ b/buildengine/testdata/externalkotlin/pom.xml @@ -9,7 +9,7 @@ 1.0-SNAPSHOT 1.8 - 2.0.0 + 2.0.10 true ${java.version} ${java.version} diff --git a/buildengine/testdata/other/go.mod b/buildengine/testdata/other/go.mod index ae7638c902..4502b1ec23 100644 --- a/buildengine/testdata/other/go.mod +++ b/buildengine/testdata/other/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/buildengine/testdata/other/go.sum b/buildengine/testdata/other/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/buildengine/testdata/other/go.sum +++ b/buildengine/testdata/other/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/cmd/ftl/testdata/go/echo/go.mod b/cmd/ftl/testdata/go/echo/go.mod index 69df181706..5db8a0dc9b 100644 --- a/cmd/ftl/testdata/go/echo/go.mod +++ b/cmd/ftl/testdata/go/echo/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/cmd/ftl/testdata/go/echo/go.sum b/cmd/ftl/testdata/go/echo/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/cmd/ftl/testdata/go/echo/go.sum +++ b/cmd/ftl/testdata/go/echo/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/cmd/ftl/testdata/go/time/go.mod b/cmd/ftl/testdata/go/time/go.mod index ce2a3974c8..45efe0f1a2 100644 --- a/cmd/ftl/testdata/go/time/go.mod +++ b/cmd/ftl/testdata/go/time/go.mod @@ -3,3 +3,45 @@ module ftl/time go 1.22.2 replace github.com/TBD54566975/ftl => ../../../../.. + +require github.com/TBD54566975/ftl v0.0.0-00010101000000-000000000000 + +require ( + connectrpc.com/connect v1.16.2 // indirect + connectrpc.com/grpcreflect v1.2.0 // indirect + connectrpc.com/otelconnect v0.7.1 // indirect + github.com/alecthomas/atomic v0.1.0-alpha2 // indirect + github.com/alecthomas/concurrency v0.0.2 // indirect + github.com/alecthomas/participle/v2 v2.1.1 // indirect + github.com/alecthomas/types v0.16.0 // indirect + github.com/alessio/shellescape v1.4.2 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/hashicorp/cronexpr v1.1.2 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.6.0 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/swaggest/jsonschema-go v0.3.72 // indirect + github.com/swaggest/refl v1.3.0 // indirect + github.com/zalando/go-keyring v0.2.5 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect +) diff --git a/cmd/ftl/testdata/go/time/go.sum b/cmd/ftl/testdata/go/time/go.sum index e69de29bb2..9fbb9ebc36 100644 --- a/cmd/ftl/testdata/go/time/go.sum +++ b/cmd/ftl/testdata/go/time/go.sum @@ -0,0 +1,148 @@ +connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE= +connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc= +connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U= +connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= +connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= +connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= +github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= +github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= +github.com/alecthomas/atomic v0.1.0-alpha2/go.mod h1:zD6QGEyw49HIq19caJDc2NMXAy8rNi9ROrxtMXATfyI= +github.com/alecthomas/concurrency v0.0.2 h1:Q3kGPtLbleMbH9lHX5OBFvJygfyFw29bXZKBg+IEVuo= +github.com/alecthomas/concurrency v0.0.2/go.mod h1:GmuQb/iHX7mbNtPlC/WDzEFxDMB0HYFer2Qda9QTs7w= +github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/types v0.16.0 h1:o9+JSwCRB6DDaWDeR/Mg7v/zh3R+MlknM6DrnDyY7U0= +github.com/alecthomas/types v0.16.0/go.mod h1:Tswm0qQpjpVq8rn70OquRsUtFxbQKub/8TMyYYGI0+k= +github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0= +github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/bool64/dev v0.2.35 h1:M17TLsO/pV2J7PYI/gpe3Ua26ETkzZGb+dC06eoMqlk= +github.com/bool64/dev v0.2.35/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= +github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= +github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= +github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= +github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= +github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= +github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU= +github.com/swaggest/jsonschema-go v0.3.72 h1:IHaGlR1bdBUBPfhe4tfacN2TGAPKENEGiNyNzvnVHv4= +github.com/swaggest/jsonschema-go v0.3.72/go.mod h1:OrGyEoVqpfSFJ4Am4V/FQcQ3mlEC1vVeleA+5ggbVW4= +github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= +github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= +github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/cmd/lint-commit-or-rollback/go.mod b/cmd/lint-commit-or-rollback/go.mod index 13c228b7a7..c000a843ce 100644 --- a/cmd/lint-commit-or-rollback/go.mod +++ b/cmd/lint-commit-or-rollback/go.mod @@ -2,14 +2,15 @@ module github.com/tbdeng/pfi/cmd/lint-commit-or-rollback go 1.22.0 -require golang.org/x/tools v0.18.0 +require golang.org/x/tools v0.24.0 require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect + golang.org/x/sync v0.8.0 // indirect ) require ( - github.com/alecthomas/assert/v2 v2.6.0 - golang.org/x/mod v0.15.0 // indirect + github.com/alecthomas/assert/v2 v2.10.0 + golang.org/x/mod v0.20.0 // indirect ) diff --git a/cmd/lint-commit-or-rollback/go.sum b/cmd/lint-commit-or-rollback/go.sum index 927131f006..23f6abe190 100644 --- a/cmd/lint-commit-or-rollback/go.sum +++ b/cmd/lint-commit-or-rollback/go.sum @@ -1,12 +1,14 @@ -github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= -github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= diff --git a/common/projectconfig/testdata/go/echo/go.mod b/common/projectconfig/testdata/go/echo/go.mod index c9547804c5..0be7eaa4c0 100644 --- a/common/projectconfig/testdata/go/echo/go.mod +++ b/common/projectconfig/testdata/go/echo/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/common/projectconfig/testdata/go/echo/go.sum b/common/projectconfig/testdata/go/echo/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/common/projectconfig/testdata/go/echo/go.sum +++ b/common/projectconfig/testdata/go/echo/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/common/projectconfig/testdata/go/findconfig/go.mod b/common/projectconfig/testdata/go/findconfig/go.mod index d01345f674..104c283923 100644 --- a/common/projectconfig/testdata/go/findconfig/go.mod +++ b/common/projectconfig/testdata/go/findconfig/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/common/projectconfig/testdata/go/findconfig/go.sum b/common/projectconfig/testdata/go/findconfig/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/common/projectconfig/testdata/go/findconfig/go.sum +++ b/common/projectconfig/testdata/go/findconfig/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/common/projectconfig/testdata/go/validateconfig/go.mod b/common/projectconfig/testdata/go/validateconfig/go.mod index de1641577d..4bca59c331 100644 --- a/common/projectconfig/testdata/go/validateconfig/go.mod +++ b/common/projectconfig/testdata/go/validateconfig/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/common/projectconfig/testdata/go/validateconfig/go.sum b/common/projectconfig/testdata/go/validateconfig/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/common/projectconfig/testdata/go/validateconfig/go.sum +++ b/common/projectconfig/testdata/go/validateconfig/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/docker-compose.yml b/docker-compose.yml index fe58670b48..72389f101b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: db: - image: postgres:15.7 + image: postgres:15.8 command: postgres user: postgres # For local debugging diff --git a/examples/go/echo/go.mod b/examples/go/echo/go.mod index 00c5d8e4db..272b973492 100644 --- a/examples/go/echo/go.mod +++ b/examples/go/echo/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/examples/go/echo/go.sum b/examples/go/echo/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/examples/go/echo/go.sum +++ b/examples/go/echo/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/extensions/vscode/package-lock.json b/extensions/vscode/package-lock.json index 5c7561223e..e0a6e3cfa5 100644 --- a/extensions/vscode/package-lock.json +++ b/extensions/vscode/package-lock.json @@ -599,9 +599,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.13.tgz", - "integrity": "sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==", + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -615,24 +615,24 @@ "dev": true }, "node_modules/@types/vscode": { - "version": "1.91.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.91.0.tgz", - "integrity": "sha512-PgPr+bUODjG3y+ozWUCyzttqR9EHny9sPAfJagddQjDwdtf66y2sDKJMnFZRuzBA2YtBGASqJGPil8VDUPvO6A==", + "version": "1.92.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.92.0.tgz", + "integrity": "sha512-DcZoCj17RXlzB4XJ7IfKdPTcTGDLYvTOcTNkvtjXWF+K2TlKzHHkBEXNWQRpBIXixNEUgx39cQeTFunY0E2msw==", "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -656,16 +656,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -685,14 +685,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -703,14 +703,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -731,9 +731,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "license": "MIT", "engines": { @@ -745,14 +745,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -774,16 +774,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -797,13 +797,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -5880,33 +5880,34 @@ } }, "node_modules/vscode-languageclient": { - "version": "10.0.0-next.9", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-10.0.0-next.9.tgz", - "integrity": "sha512-DHEpX7EOCnI2DI5MzE3WknHIcJ29f1mUf058KjFY5PTqfV7HFpBIFPp35LipQ6zYTZN4oAgXUoitfmzvmBqVpQ==", + "version": "10.0.0-next.11", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-10.0.0-next.11.tgz", + "integrity": "sha512-zoQrt0jtA6khVh/Oe+IURyayrOPlAyxkhlaCtKE5EaW6xwlLSsRKvk3GnR6zMRy7tEXbmhEGQsluV/ZAF7oi1A==", "license": "MIT", "dependencies": { "minimatch": "^9.0.3", "semver": "^7.6.0", - "vscode-languageserver-protocol": "3.17.6-next.7" + "vscode-languageserver-protocol": "3.17.6-next.9" }, "engines": { "vscode": "^1.91.0" } }, "node_modules/vscode-languageserver-protocol": { - "version": "3.17.6-next.7", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.6-next.7.tgz", - "integrity": "sha512-lx8BQ94x6jl6ZzZOrsN4RxwA1Xh0Ovpus+pWA9TXYF5A9EAAL+pTgYFRra3byucdjw3GDC6zbj7wviyfkMgYuA==", + "version": "3.17.6-next.9", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.6-next.9.tgz", + "integrity": "sha512-p4ddqAZa55xzkowM1zpMcQzAh0E1cUWBnQtr6lsXEJ4QupixMVWe53F9vbLbXCN6R/K5uNUaa861c2yS3tcEFw==", "license": "MIT", "dependencies": { "vscode-jsonrpc": "9.0.0-next.5", - "vscode-languageserver-types": "3.17.6-next.4" + "vscode-languageserver-types": "3.17.6-next.5" } }, "node_modules/vscode-languageserver-types": { - "version": "3.17.6-next.4", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.6-next.4.tgz", - "integrity": "sha512-SeJTpH/S14EbxOAVaOUoGVqPToqpRTld5QO5Ghig3AlbFJTFF9Wu7srHMfa85L0SX1RYAuuCSFKJVVCxDIk1/Q==" + "version": "3.17.6-next.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.6-next.5.tgz", + "integrity": "sha512-QFmf3Yl1tCgUQfA77N9Me/LXldJXkIVypQbty2rJ1DNHQkC+iwvm4Z2tXg9czSwlhvv0pD4pbF5mT7WhAglolw==", + "license": "MIT" }, "node_modules/watchpack": { "version": "2.4.1", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b51ea3e533..abba6a30d5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -29,7 +29,7 @@ "json-schema-faker": "0.5.6", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.25.1", + "react-router-dom": "6.26.0", "react-use": "^17.5.0", "reactflow": "11.11.4", "tailwindcss": "^3.3.3", @@ -57,8 +57,8 @@ "eslint-plugin-react": "7.35.0", "eslint-plugin-storybook": "^0.8.0", "fast-glob": "3.3.2", - "lint-staged": "15.2.7", - "postcss": "8.4.40", + "lint-staged": "15.2.8", + "postcss": "8.4.41", "postcss-nesting": "12.1.5", "storybook": "^8.2.7", "storybook-dark-mode": "^4.0.2", @@ -2280,9 +2280,9 @@ "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" }, "node_modules/@codemirror/view": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.29.0.tgz", - "integrity": "sha512-ED4ims4fkf7eOA+HYLVP8VVg3NMllt1FPm9PEJBfYFnidKlRITBaua38u68L1F60eNtw2YNcDN5jsIzhKZwWQA==", + "version": "6.30.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.30.0.tgz", + "integrity": "sha512-96Nmn8OeLh6aONQprIeYk8hGVnEuYpWuxKSkdsODOx9hWPxyuyZGvmvxV/JmLsp+CubMO1PsLaN5TNNgrl0UrQ==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.4.0", @@ -4639,9 +4639,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", - "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz", + "integrity": "sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -4708,10 +4708,11 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.7.tgz", - "integrity": "sha512-wDnMGGmaogAForkNncfCx8BEDiwxeK8zC0lj8HkRPUuH6vTr81U5RIb12Wa2TnnNKLKMFAtyPSnofHf3OAfzZQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.8.tgz", + "integrity": "sha512-dyajqsMNAUktpi7aiml0Fsm4ey8Nh2YwRyTDuTJZ1iJFcFyARqfr5iKH4/qElq80y0FYXGgGRJB+dKJsCdefLw==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@types/uuid": "^9.0.1", @@ -4724,14 +4725,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.7.tgz", - "integrity": "sha512-kEL3kzYB0qNfpznchlGBnQm4iydyzdTYDPlCFsKUAxfUmJFnpz2H52Sl5lB+qJC/4OREp1Usltag7cUjeuyzMQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.8.tgz", + "integrity": "sha512-OqXGpq8KzWwAAQWPnby/v4ayWuUAB18Twgi6zeb+QNLEQdFnSp7kz6+4mP8ZVg8RS3ACGXD31nnvvlF7GYoJjQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3", @@ -4742,14 +4744,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-controls": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.7.tgz", - "integrity": "sha512-u3MruX0Zh6l1iNkoJdXwx+zPVqpDKypVrC0YdN3qQ3+mtTwqt35rgetYqtOkDnJ8mXKxo8A5giERKPIyzH9iBA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.8.tgz", + "integrity": "sha512-adhg68CSFaR/r95rgyKU4ZzWwZz+MU0c4vr9hqrR1UGvg/zl33IZQQzb5j5v3Axo0O31yPMaY6LRty7pOv3+/Q==", "dev": true, + "license": "MIT", "dependencies": { "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -4760,21 +4763,22 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-docs": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.7.tgz", - "integrity": "sha512-icLbvUWp95WUxq2sY+0xgJ49MaQ2HqtWY9RUJUZswJ/ZPJTCCpIoa6HP/NOB9A90Oec9n8sW+1CdDL4CxfxfZg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.8.tgz", + "integrity": "sha512-8hqUYYveJjR3e/XdXt0vduA7TxFRIFWgXoa9jN5axa63kqfiHcfkpFYPjM8jCRhsfDIRgdrwe2qxsA0wewO1pA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.2.7", - "@storybook/csf-plugin": "8.2.7", + "@storybook/blocks": "8.2.8", + "@storybook/csf-plugin": "8.2.8", "@storybook/global": "^5.0.0", - "@storybook/react-dom-shim": "8.2.7", + "@storybook/react-dom-shim": "8.2.8", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "fs-extra": "^11.1.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", @@ -4788,24 +4792,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.7.tgz", - "integrity": "sha512-5qe7La9B2Z4Y9Fet3C35y8zOZwKgrqduNk8yAUmPRAOwopdo8SGKYpnFTnAtTfTCVk6Y+AZlRfQq0yLUk0Wl3g==", - "dev": true, - "dependencies": { - "@storybook/addon-actions": "8.2.7", - "@storybook/addon-backgrounds": "8.2.7", - "@storybook/addon-controls": "8.2.7", - "@storybook/addon-docs": "8.2.7", - "@storybook/addon-highlight": "8.2.7", - "@storybook/addon-measure": "8.2.7", - "@storybook/addon-outline": "8.2.7", - "@storybook/addon-toolbars": "8.2.7", - "@storybook/addon-viewport": "8.2.7", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.8.tgz", + "integrity": "sha512-NRbFv2ociM1l/Oi/1go/ZC5bUU41n9aKD1DzIbguEKBhUs/TGAES+f5x+7DvYnt3Hvd925/FyTXuMU+vNUeiUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/addon-actions": "8.2.8", + "@storybook/addon-backgrounds": "8.2.8", + "@storybook/addon-controls": "8.2.8", + "@storybook/addon-docs": "8.2.8", + "@storybook/addon-highlight": "8.2.8", + "@storybook/addon-measure": "8.2.8", + "@storybook/addon-outline": "8.2.8", + "@storybook/addon-toolbars": "8.2.8", + "@storybook/addon-viewport": "8.2.8", "ts-dedent": "^2.0.0" }, "funding": { @@ -4813,14 +4818,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.7.tgz", - "integrity": "sha512-YhiLtyJ3NBNV3FQoQo8RFjj59QGSmmeSwRvCjoac6No2DY5vkMW5a8mW6ORr6QYd7ratRNtd3AsPqksZIehRwQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.8.tgz", + "integrity": "sha512-IM1pPx6CCZbHV0bv3oB1qBCGDsr8soq7XLl93tc7mc4hstWSDFfNn7rx4CWycSlCqXlNTKh8cEkbrPrhV9cwbg==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0" }, @@ -4829,18 +4835,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.7.tgz", - "integrity": "sha512-WZXlwpBNLE483uKuR70A7nm+ZbcZNEmuVz/J1/u7dbi0BUWzmJUa9YIgVeQ/1KTwW8KTkxvB0TuUUH3aA4ZKlA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.8.tgz", + "integrity": "sha512-ggctlrSlK72xMfhviHHRslZF5tr9aHr1VFwCG/tjF7s1lM3S7OGqgHLJpcja/wNREvq9GMEvX95ZSu5NMh5CtA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.2.7", - "@storybook/test": "8.2.7", + "@storybook/instrumenter": "8.2.8", + "@storybook/test": "8.2.8", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -4849,14 +4856,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-links": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.7.tgz", - "integrity": "sha512-BJdR+vdj7S6Rtx8XqBNQzLsRGH/FYHJ6B6BPWGp0awVx0jNWJnxepINQov8i+GAddUVQGCNG+r4LI3QSD3tNAA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.8.tgz", + "integrity": "sha512-2igEaSdKAFjKjioT6LGdBxZulpbVCzmlmV//sTu3sQiVnnxRjjGFt77sEeLMajrsSvg9DB1RMbDsvJ4FJTzXfQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@storybook/global": "^5.0.0", @@ -4868,7 +4876,7 @@ }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.2.7" + "storybook": "^8.2.8" }, "peerDependenciesMeta": { "react": { @@ -4877,10 +4885,11 @@ } }, "node_modules/@storybook/addon-measure": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.7.tgz", - "integrity": "sha512-cS5njwlzrgrUjigUKjhbgJMT8bhPmVDK3FwrQqGhw6xYP4cd9/YBJ4RLNPWhOgGJ+EUTz7eFZ/Rkli5mNrhYcQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.8.tgz", + "integrity": "sha512-oqZiX571F9NNy8o/oVyM1Pe2cJz3WJ/OpL0lVbepHrV4ir1f+SDYZdMI58jGBAtoM52cwFc2ZPbzXKQs7a513A==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "tiny-invariant": "^1.3.1" @@ -4890,14 +4899,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-onboarding": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.2.7.tgz", - "integrity": "sha512-YgpQY0uhYRi+3vny2BjnFlY19ga9/GGZlcFTfaf2wCO7KhjXdES3bp4VTtdNkAwbVaXYY+b33ERd4x1UQ7jSkA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.2.8.tgz", + "integrity": "sha512-fKy3uwggIZKFQL9qo4niVYnAhMAdO/xBsEzJNj2ueTaWoJYO6c0jDWhVQW3pxlMw6yq/WdYT6tW/lsbHKFBUVQ==", "dev": true, + "license": "MIT", "dependencies": { "react-confetti": "^6.1.0" }, @@ -4906,14 +4916,15 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-outline": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.7.tgz", - "integrity": "sha512-oFSo3o5eEUSsdGUSPV22pGoJ5lL0PGcqjcee2hyl0Rc60ovsnB1BEGOoaGk7/bmkywMxRZm8D6j85V8HftA/kg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.8.tgz", + "integrity": "sha512-Cbk4Z0ojggiXjpbS2c4WUP56yikQdT4O7+8AuBNNjVUHNvJQADWYovi6SvDmrS5dH1iyIkB+4saXMr0syp+BDw==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "ts-dedent": "^2.0.0" @@ -4923,7 +4934,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-styling": { @@ -5120,10 +5131,11 @@ } }, "node_modules/@storybook/addon-themes": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.2.7.tgz", - "integrity": "sha512-LlQFHfC5CicQ7urPMOjhqGyKN8Tm+4mVw4mI7+FGnPkUUcBwxw85OcbtdXQgzfU4AlRauBkIz0CW/tbhSR8R/A==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.2.8.tgz", + "integrity": "sha512-lJzLAAs2gPm0fbE+NB7oQSbetQoENe3jrlb+vUemUpGBJuhiiz+Aue47DEiFtWCzeNze6dhigMJKFlFacvLz+A==", "dev": true, + "license": "MIT", "dependencies": { "ts-dedent": "^2.0.0" }, @@ -5132,27 +5144,29 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.7.tgz", - "integrity": "sha512-lEq0/uiogQSxS8pM5AqIexPiG2mudHUxgBiVWSspbTQDUbGBUxB64VYeYERat50N/GyS2iCymlfSkC+OUXaYLQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.8.tgz", + "integrity": "sha512-k64G3FUpX3H/mhJ7AG1r/4Drsk6cdUtxI3yVdgWb7O3Ka7v/OFZexRXRSiV03n5q/kaqVKDu96Tuog57+7EB4w==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.7.tgz", - "integrity": "sha512-d4+klwM/duTukNED1WCeBgIMqL5Jvm/iUs2rUc5HI1FGMEDYnoLVR2ztjivQs+6f1cJWuGwWZD/toB5pKHuR/A==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.8.tgz", + "integrity": "sha512-/JZeIgB33yhryUvWaNO+3t9akcS8nGLyAUmlljPFr3LUDDYrO/0H9tE4CgjLqtwCXBq3k3s0HLzEJOrKI9Tmbw==", "dev": true, + "license": "MIT", "dependencies": { "memoizerific": "^1.11.3" }, @@ -5161,7 +5175,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/api": { @@ -5287,10 +5301,11 @@ } }, "node_modules/@storybook/blocks": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.7.tgz", - "integrity": "sha512-lZB4EzmY4ftgubkf7hmkALEhmfMhRkDRD5QjrgTZLRpdVXPzFUyljgLlTBhv34YTN+ZLYK618/4uSVJBpgoKeQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.8.tgz", + "integrity": "sha512-AHBXu9s73Xv9r1JageIL7C4eGf5XYEByai4Y6NYQsE+jF7b7e8oaSUoLW6fWSyLGuqvjRx+5P7GMNI2K1EngBA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@storybook/global": "^5.0.0", @@ -5314,7 +5329,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.2.7" + "storybook": "^8.2.8" }, "peerDependenciesMeta": { "react": { @@ -5330,6 +5345,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5341,15 +5357,17 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/builder-vite": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.2.7.tgz", - "integrity": "sha512-CoEQjsfAQdZeAavfh1sBTMmC453kUFLKHr1zs6MZAlkejxky+U21t1Zb1qEU+IsEr/AlzvJr60pxUNL/dy6PVQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.2.8.tgz", + "integrity": "sha512-p9EJfZkX9ZsVi1Qr3jYyCJaZZ/2pt0KVTOYnDzNnhi3P/suU6O3Lp/YCV5+KOfAmlg2IgTND0EidqZinqPIBSg==", "dev": true, + "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "8.2.7", + "@storybook/csf-plugin": "8.2.8", "@types/find-cache-dir": "^3.2.1", "browser-assert": "^1.2.1", "es-module-lexer": "^1.5.0", @@ -5365,7 +5383,7 @@ }, "peerDependencies": { "@preact/preset-vite": "*", - "storybook": "^8.2.7", + "storybook": "^8.2.8", "typescript": ">= 4.3.x", "vite": "^4.0.0 || ^5.0.0", "vite-plugin-glimmerx": "*" @@ -5440,15 +5458,16 @@ } }, "node_modules/@storybook/codemod": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.7.tgz", - "integrity": "sha512-D2sJcZMUO6Y7DNja4LvdT6uBee4bZbQKB904kEG9Kpr0XF20IHAP9BbkfG8HEFaS0GbJwvGvE03Sg+S1y+vO6Q==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.8.tgz", + "integrity": "sha512-dqD4j6JTsS8BM2y1yHBIe5fHvsGM08qpJQXkE77aXJIm5UfUeuWC7rY0xAheX3fU5G98l3BJk0ySUGspQL5pNg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/preset-env": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/core": "8.2.7", + "@storybook/core": "8.2.8", "@storybook/csf": "0.1.11", "@types/cross-spawn": "^6.0.2", "cross-spawn": "^7.0.3", @@ -5509,23 +5528,25 @@ } }, "node_modules/@storybook/components": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.2.7.tgz", - "integrity": "sha512-FXhnoHl9S+tKSFc62iUG3EWplQP9ojGQaSMhqP4QTus6xmo53oSsPzuTPQilKVHkGxFQW8eGgKKsfHw3G2NT2g==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.2.8.tgz", + "integrity": "sha512-d4fI7Clogx4rgLAM7vZVr9L2EFtAkGXvpkZFuB0H0eyYaxZSbuZYvDCzRglQGQGsqD8IA8URTgPVSXC3L3k6Bg==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/core": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.7.tgz", - "integrity": "sha512-vgw5MYN9Bq2/ZsObCOEHbBHwi4RpbYCHPFtKkr4kTnWID++FCSiSVd7jY3xPvcNxWqCxOyH6dThpBi+SsB/ZAA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.8.tgz", + "integrity": "sha512-Wwm/Txh87hbxqU9OaxXwdGAmdRBjDn7rlZEPjNBx0tt43SQ11fKambY7nVWrWuw46YsJpdF9V/PQr4noNEXXEA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@types/express": "^4.17.21", @@ -5730,6 +5751,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -5744,10 +5766,11 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.7.tgz", - "integrity": "sha512-rBdplL6xcVJcuq+uM0eidomMQ5BtAlVAejYrOTNiqBk/zVh5JSvchYzYG9n6Fo2PdKLLKdlZ874zhsVuNriNBQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.8.tgz", + "integrity": "sha512-CEHY7xloBPE8d8h0wg2AM2kRaZkHK8/vkYMNZPbccqAYj6PQIdTuOcXZIBAhAGydyIBULZmsmmsASxM9RO5fKA==", "dev": true, + "license": "MIT", "dependencies": { "unplugin": "^1.3.1" }, @@ -5756,7 +5779,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/csf/node_modules/type-fest": { @@ -5791,10 +5814,11 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.7.tgz", - "integrity": "sha512-Zm6Ty4uWFTNchKUviuJ9vfcMb7+qU8eyrFXVY80XRpr62JEWkYj4eCwx4OG8GzlQahTh9aSv9+hzV6p/5Ld4mw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.8.tgz", + "integrity": "sha512-6Gk3CzoYQQXBXpW86PKqYSozOB/C9dSYiFvwPRo4XsEfjARDi8yglqkbOtG+FVqKDL66I5krcveB8bTWigqc9g==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@vitest/utils": "^1.3.1", @@ -5805,20 +5829,21 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/manager-api": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.2.7.tgz", - "integrity": "sha512-BXjz6eNl1GyFcMwzRQTIokslcIY71AYblJUscPcy03X93oqI0GjFVa1xuSMwYw/oXWn7SHhKmqtqEG19lvBGRQ==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.2.8.tgz", + "integrity": "sha512-wzfRu3vrD9a99pN3W/RJXVtgNGNsy9PyvetjUfgQVtUZ9eXXDuA+tM7ITTu3xvONtV/rT2YEBwzOpowa+r1GNQ==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/node-logger": { @@ -5832,30 +5857,32 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.2.7.tgz", - "integrity": "sha512-lNZBTjZaYNSwBY8dEcDZdkOBvq1/JoVWpuvqDEKvGmp5usTe77xAOwGyncEb96Cx1BbXXkMiDrqbV5G23PFRYA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.2.8.tgz", + "integrity": "sha512-BDt1lo5oEWAaTVCsl6JUHCBFtIWI/Za4qvIdn2Lx9eCA+Ae6IDliosmu273DcvGD9R4OPF6sm1dML3TXILGGcA==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/react": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.7.tgz", - "integrity": "sha512-Qkw1K1iBDk+E9dlHrEWOOkn0trUU6wSt4mvzyOekiApM290esnPtw6GYXvxfBgFwNXfXbaGG3QNYGAFevf7qHw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.8.tgz", + "integrity": "sha512-Nln0DDTQ930P4J+SEkWbLSgaDe8eDd5gP6h3l4b5RwT7sRuSyHtTtYHPCnU9U7sLQ3AbMsclgtJukHXDitlccg==", "dev": true, + "license": "MIT", "dependencies": { - "@storybook/components": "^8.2.7", + "@storybook/components": "^8.2.8", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "^8.2.7", - "@storybook/preview-api": "^8.2.7", - "@storybook/react-dom-shim": "8.2.7", - "@storybook/theming": "^8.2.7", + "@storybook/manager-api": "^8.2.8", + "@storybook/preview-api": "^8.2.8", + "@storybook/react-dom-shim": "8.2.8", + "@storybook/theming": "^8.2.8", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", "@types/node": "^18.0.0", @@ -5882,7 +5909,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.2.7", + "storybook": "^8.2.8", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -5892,10 +5919,11 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.7.tgz", - "integrity": "sha512-9VI+NrC09DAr0QQZsFmU5Fd9eqdJp/1AHK+sm9BOZretGGGJwn22xS7UXhHIiFpfXJQnr3TNcYWRzXFyuaE/Sw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.8.tgz", + "integrity": "sha512-2my3dGBOpBe30+FsSdQOIYCfxMyT68+SEq0qcXxfuax0BkhhJnZLpwvpqOna6EOVTgBD+Tk1TKmjpGwxuwp4rg==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -5903,19 +5931,20 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/react-vite": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.2.7.tgz", - "integrity": "sha512-OvC4c4VpMbMNWNR8zBfWPwSS+LilMZ5O7cUbFSFOsAAI5cYcReo1d0MqpiaWybQynkBFj81zRT+dr+B/5Y2Ajg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.2.8.tgz", + "integrity": "sha512-xzXWyhFnLoFtJGgj8F5j/33QB4YTyEX61On6kolt7WFAjRFaUWJGYUC8cPPL4PNwsdouyCrnHvlJj77AvFlvfQ==", "dev": true, + "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.3.1", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "8.2.7", - "@storybook/react": "8.2.7", + "@storybook/builder-vite": "8.2.8", + "@storybook/react": "8.2.8", "find-up": "^5.0.0", "magic-string": "^0.30.0", "react-docgen": "^7.0.0", @@ -5932,7 +5961,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.2.7", + "storybook": "^8.2.8", "vite": "^4.0.0 || ^5.0.0" } }, @@ -5941,6 +5970,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5958,6 +5988,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -5967,6 +5998,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5979,6 +6011,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -6015,13 +6048,14 @@ } }, "node_modules/@storybook/test": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.7.tgz", - "integrity": "sha512-7xypGR0zjJaM5MkxIz513SYiGs5vDJZL1bbkG1YKeBMff+ZRpa8y8VDYn/WDWuDw76KcFEXoPsPzKwktGhvnpw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.8.tgz", + "integrity": "sha512-Lbt4DHP8WhnakTPw981kP85DeoONKN+zVLjFPa5ptllyT+jazZANjIdGhNUlBdIzOw3oyDXhGlWIdtqztS3pSA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", - "@storybook/instrumenter": "8.2.7", + "@storybook/instrumenter": "8.2.8", "@testing-library/dom": "10.1.0", "@testing-library/jest-dom": "6.4.5", "@testing-library/user-event": "14.5.2", @@ -6034,20 +6068,21 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/theming": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.2.7.tgz", - "integrity": "sha512-+iqm0GfRkshrjjNSOzwl7AD2m+LtJGXJCr93ke1huDK497WUKbX1hbbw51h5E1tEkx0c2wIqUlaqCM+7XMYcpw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.2.8.tgz", + "integrity": "sha512-jt5oUO82LN3z5aygNdHucBZcErSicIAwzhR5Kz9E/C9wUbhyZhbWsWyhpZaytu8LJUj2YWAIPS8kq/jGx+qLZA==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.2.7" + "storybook": "^8.2.8" } }, "node_modules/@storybook/types": { @@ -6872,17 +6907,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -6906,16 +6941,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -6935,14 +6970,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -6953,14 +6988,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -6981,9 +7016,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "license": "MIT", "engines": { @@ -6995,14 +7030,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7024,16 +7059,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -7047,13 +7082,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -7541,12 +7576,16 @@ } }, "node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8279,15 +8318,16 @@ "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==" }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, + "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8944,9 +8984,10 @@ "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -9246,6 +9287,19 @@ "node": ">=4" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -12184,22 +12238,22 @@ } }, "node_modules/lint-staged": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", - "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.8.tgz", + "integrity": "sha512-PUWFf2zQzsd9EFU+kM1d7UP+AZDbKFKuj+9JNVTBkhUFhbg4MAt6WfyMMwBfM4lYqd4D2Jwac5iuTu9rVj4zCQ==", "dev": true, "license": "MIT", "dependencies": { "chalk": "~5.3.0", "commander": "~12.1.0", - "debug": "~4.3.4", + "debug": "~4.3.6", "execa": "~8.0.1", - "lilconfig": "~3.1.1", - "listr2": "~8.2.1", + "lilconfig": "~3.1.2", + "listr2": "~8.2.4", "micromatch": "~4.0.7", "pidtree": "~0.6.0", "string-argv": "~0.3.2", - "yaml": "~2.4.2" + "yaml": "~2.5.0" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -12225,16 +12279,17 @@ } }, "node_modules/listr2": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.1.tgz", - "integrity": "sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, "engines": { @@ -12385,14 +12440,15 @@ } }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -12408,6 +12464,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -12420,6 +12477,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -12432,6 +12490,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", "dev": true, + "license": "MIT", "dependencies": { "get-east-asian-width": "^1.0.0" }, @@ -12447,6 +12506,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -12463,6 +12523,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -12691,6 +12752,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -13686,9 +13760,9 @@ } }, "node_modules/postcss": { - "version": "8.4.40", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", - "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "funding": [ { "type": "opencollective", @@ -14010,6 +14084,7 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -14348,12 +14423,12 @@ } }, "node_modules/react-router": { - "version": "6.25.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", - "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.0.tgz", + "integrity": "sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.18.0" + "@remix-run/router": "1.19.0" }, "engines": { "node": ">=14.0.0" @@ -14363,13 +14438,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.25.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", - "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.0.tgz", + "integrity": "sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.18.0", - "react-router": "6.25.1" + "@remix-run/router": "1.19.0", + "react-router": "6.26.0" }, "engines": { "node": ">=14.0.0" @@ -14751,51 +14826,38 @@ "dev": true }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -15364,15 +15426,16 @@ "dev": true }, "node_modules/storybook": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.7.tgz", - "integrity": "sha512-Jb9DXue1sr3tKkpuq66VP5ItOKTpxL6t99ze1wXDbjCvPiInTdPA5AyFEjBuKjOBIh28bayYoOZa6/xbMJV+Wg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.8.tgz", + "integrity": "sha512-sh4CNCXkieVgJ5GXrCOESS0BjRbQ9wG7BVnurQPl6izNnB9zR8rag+aUmjPZWBwbj55V1BFA5A/vEsCov21qjg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/codemod": "8.2.7", - "@storybook/core": "8.2.7", + "@storybook/codemod": "8.2.8", + "@storybook/core": "8.2.8", "@types/semver": "^7.3.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", @@ -15429,6 +15492,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -15444,6 +15508,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -15460,6 +15525,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -15471,13 +15537,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/storybook/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -15487,6 +15555,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -15510,6 +15579,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -15522,6 +15592,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", @@ -15542,6 +15613,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -15551,6 +15623,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -15560,6 +15633,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -15572,6 +15646,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -15581,6 +15656,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -15593,6 +15669,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -15608,6 +15685,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -15619,13 +15697,15 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/storybook/node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -15638,6 +15718,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -15647,6 +15728,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -16010,9 +16092,9 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, "node_modules/tailwindcss": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz", - "integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz", + "integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -16457,9 +16539,9 @@ } }, "node_modules/type-fest": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz", - "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.24.0.tgz", + "integrity": "sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" @@ -17337,6 +17419,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -17427,6 +17510,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -17439,6 +17523,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -17451,6 +17536,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -17489,6 +17575,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -17520,9 +17607,10 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "license": "ISC", "bin": { "yaml": "bin.mjs" }, diff --git a/frontend/package.json b/frontend/package.json index 2c5f26fa1e..801ae5eb90 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,7 +44,7 @@ "json-schema-faker": "0.5.6", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.25.1", + "react-router-dom": "6.26.0", "react-use": "^17.5.0", "reactflow": "11.11.4", "tailwindcss": "^3.3.3", @@ -72,8 +72,8 @@ "eslint-plugin-react": "7.35.0", "eslint-plugin-storybook": "^0.8.0", "fast-glob": "3.3.2", - "lint-staged": "15.2.7", - "postcss": "8.4.40", + "lint-staged": "15.2.8", + "postcss": "8.4.41", "postcss-nesting": "12.1.5", "storybook": "^8.2.7", "storybook-dark-mode": "^4.0.2", diff --git a/go-runtime/compile/testdata/go/echo/go.mod b/go-runtime/compile/testdata/go/echo/go.mod index 767d3bd24f..0f9dc388ce 100644 --- a/go-runtime/compile/testdata/go/echo/go.mod +++ b/go-runtime/compile/testdata/go/echo/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/compile/testdata/go/echo/go.sum b/go-runtime/compile/testdata/go/echo/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/compile/testdata/go/echo/go.sum +++ b/go-runtime/compile/testdata/go/echo/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/compile/testdata/go/notexportedverb/go.mod b/go-runtime/compile/testdata/go/notexportedverb/go.mod index 8b64312e83..2b8282d901 100644 --- a/go-runtime/compile/testdata/go/notexportedverb/go.mod +++ b/go-runtime/compile/testdata/go/notexportedverb/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/compile/testdata/go/notexportedverb/go.sum b/go-runtime/compile/testdata/go/notexportedverb/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/compile/testdata/go/notexportedverb/go.sum +++ b/go-runtime/compile/testdata/go/notexportedverb/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/compile/testdata/go/one/go.mod b/go-runtime/compile/testdata/go/one/go.mod index 73340f94f7..524102f091 100644 --- a/go-runtime/compile/testdata/go/one/go.mod +++ b/go-runtime/compile/testdata/go/one/go.mod @@ -7,9 +7,9 @@ replace github.com/TBD54566975/ftl => ../../../../.. require github.com/TBD54566975/ftl v0.150.3 require ( - connectrpc.com/connect v1.16.1 // indirect + connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect - connectrpc.com/otelconnect v0.7.0 // indirect + connectrpc.com/otelconnect v0.7.1 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect @@ -29,19 +29,19 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/puzpuzpuz/xsync/v3 v3.3.1 // indirect + github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/compile/testdata/go/one/go.sum b/go-runtime/compile/testdata/go/one/go.sum index 38d5d1435e..9fbb9ebc36 100644 --- a/go-runtime/compile/testdata/go/one/go.sum +++ b/go-runtime/compile/testdata/go/one/go.sum @@ -1,9 +1,9 @@ -connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis= -connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw= +connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE= +connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc= connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U= connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= -connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY= -connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc= +connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= +connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= @@ -74,8 +74,8 @@ github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/puzpuzpuz/xsync/v3 v3.3.1 h1:vZPJk3OOfoaSjy3cdTX3BZxhDCUVp9SqdHnd+ilGlbQ= -github.com/puzpuzpuz/xsync/v3 v3.3.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= +github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -134,14 +134,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M= -modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= -modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/compile/testdata/go/two/go.mod b/go-runtime/compile/testdata/go/two/go.mod index e009521704..9963efd3a7 100644 --- a/go-runtime/compile/testdata/go/two/go.mod +++ b/go-runtime/compile/testdata/go/two/go.mod @@ -7,9 +7,9 @@ replace github.com/TBD54566975/ftl => ../../../../.. require github.com/TBD54566975/ftl v0.150.3 require ( - connectrpc.com/connect v1.16.1 // indirect + connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect - connectrpc.com/otelconnect v0.7.0 // indirect + connectrpc.com/otelconnect v0.7.1 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect @@ -29,19 +29,19 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/puzpuzpuz/xsync/v3 v3.3.1 // indirect + github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/compile/testdata/go/two/go.sum b/go-runtime/compile/testdata/go/two/go.sum index 38d5d1435e..9fbb9ebc36 100644 --- a/go-runtime/compile/testdata/go/two/go.sum +++ b/go-runtime/compile/testdata/go/two/go.sum @@ -1,9 +1,9 @@ -connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis= -connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw= +connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE= +connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc= connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U= connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= -connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY= -connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc= +connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= +connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= @@ -74,8 +74,8 @@ github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/puzpuzpuz/xsync/v3 v3.3.1 h1:vZPJk3OOfoaSjy3cdTX3BZxhDCUVp9SqdHnd+ilGlbQ= -github.com/puzpuzpuz/xsync/v3 v3.3.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= +github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -134,14 +134,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M= -modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= -modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/compile/testdata/go/undefinedverb/go.mod b/go-runtime/compile/testdata/go/undefinedverb/go.mod index 8b64312e83..2b8282d901 100644 --- a/go-runtime/compile/testdata/go/undefinedverb/go.mod +++ b/go-runtime/compile/testdata/go/undefinedverb/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/compile/testdata/go/undefinedverb/go.sum b/go-runtime/compile/testdata/go/undefinedverb/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/compile/testdata/go/undefinedverb/go.sum +++ b/go-runtime/compile/testdata/go/undefinedverb/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/encoding/testdata/go/omitempty/go.mod b/go-runtime/encoding/testdata/go/omitempty/go.mod index 243cd594e7..334871780d 100644 --- a/go-runtime/encoding/testdata/go/omitempty/go.mod +++ b/go-runtime/encoding/testdata/go/omitempty/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/encoding/testdata/go/omitempty/go.sum b/go-runtime/encoding/testdata/go/omitempty/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/encoding/testdata/go/omitempty/go.sum +++ b/go-runtime/encoding/testdata/go/omitempty/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/ftltest/testdata/go/outer/go.sum b/go-runtime/ftl/ftltest/testdata/go/outer/go.sum index 79591ce1b4..f7b40ba4c0 100644 --- a/go-runtime/ftl/ftltest/testdata/go/outer/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/outer/go.sum @@ -96,20 +96,20 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= @@ -122,8 +122,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod index ccd3eb15e3..12577fc3df 100644 --- a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod @@ -44,19 +44,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod index 1c555bd415..1202106777 100644 --- a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod @@ -44,19 +44,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod index 62da59be9f..cc87108068 100644 --- a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod @@ -44,18 +44,19 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod index 814d17f7d9..4c7cf792d3 100644 --- a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod @@ -42,19 +42,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod index 2f52025d2e..f190123044 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod @@ -39,13 +39,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/testdata/go/echo/go.mod b/go-runtime/ftl/testdata/go/echo/go.mod index 273a160e9f..b10462c9d7 100644 --- a/go-runtime/ftl/testdata/go/echo/go.mod +++ b/go-runtime/ftl/testdata/go/echo/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/testdata/go/echo/go.sum b/go-runtime/ftl/testdata/go/echo/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/ftl/testdata/go/echo/go.sum +++ b/go-runtime/ftl/testdata/go/echo/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/testdata/go/mapper/go.mod b/go-runtime/ftl/testdata/go/mapper/go.mod index f0e05325aa..144ee4c71e 100644 --- a/go-runtime/ftl/testdata/go/mapper/go.mod +++ b/go-runtime/ftl/testdata/go/mapper/go.mod @@ -44,19 +44,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/testdata/go/mapper/go.sum b/go-runtime/ftl/testdata/go/mapper/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/testdata/go/mapper/go.sum +++ b/go-runtime/ftl/testdata/go/mapper/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/ftl/testdata/go/typeregistry/go.mod b/go-runtime/ftl/testdata/go/typeregistry/go.mod index e122cb865e..d087998d1e 100644 --- a/go-runtime/ftl/testdata/go/typeregistry/go.mod +++ b/go-runtime/ftl/testdata/go/typeregistry/go.mod @@ -44,19 +44,20 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/sqlc-dev/pqtype v0.3.0 // indirect github.com/swaggest/jsonschema-go v0.3.72 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/zalando/go-keyring v0.2.5 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/ftl/testdata/go/typeregistry/go.sum b/go-runtime/ftl/testdata/go/typeregistry/go.sum index d17b6aea5f..1ed06cc1b0 100644 --- a/go-runtime/ftl/testdata/go/typeregistry/go.sum +++ b/go-runtime/ftl/testdata/go/typeregistry/go.sum @@ -118,6 +118,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk= +github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -147,21 +149,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -176,8 +178,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/internal/testdata/go/mapper/go.mod b/go-runtime/internal/testdata/go/mapper/go.mod index ff497ddba4..08209801e2 100644 --- a/go-runtime/internal/testdata/go/mapper/go.mod +++ b/go-runtime/internal/testdata/go/mapper/go.mod @@ -38,12 +38,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/internal/testdata/go/mapper/go.sum b/go-runtime/internal/testdata/go/mapper/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/internal/testdata/go/mapper/go.sum +++ b/go-runtime/internal/testdata/go/mapper/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/scaffolding/bin/.go-1.22.5.pkg b/go-runtime/scaffolding/bin/.go-1.22.6.pkg similarity index 100% rename from go-runtime/scaffolding/bin/.go-1.22.5.pkg rename to go-runtime/scaffolding/bin/.go-1.22.6.pkg diff --git a/go-runtime/scaffolding/bin/go b/go-runtime/scaffolding/bin/go index 5c26cb9eda..fec23e291d 120000 --- a/go-runtime/scaffolding/bin/go +++ b/go-runtime/scaffolding/bin/go @@ -1 +1 @@ -.go-1.22.5.pkg \ No newline at end of file +.go-1.22.6.pkg \ No newline at end of file diff --git a/go-runtime/scaffolding/bin/gofmt b/go-runtime/scaffolding/bin/gofmt index 5c26cb9eda..fec23e291d 120000 --- a/go-runtime/scaffolding/bin/gofmt +++ b/go-runtime/scaffolding/bin/gofmt @@ -1 +1 @@ -.go-1.22.5.pkg \ No newline at end of file +.go-1.22.6.pkg \ No newline at end of file diff --git a/go-runtime/schema/testdata/failing/go.mod b/go-runtime/schema/testdata/failing/go.mod index 20e11036ae..2b0089e252 100644 --- a/go-runtime/schema/testdata/failing/go.mod +++ b/go-runtime/schema/testdata/failing/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/failing/go.sum b/go-runtime/schema/testdata/failing/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/failing/go.sum +++ b/go-runtime/schema/testdata/failing/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/fsm/go.mod b/go-runtime/schema/testdata/fsm/go.mod index a36b3949cb..51d60813d7 100644 --- a/go-runtime/schema/testdata/fsm/go.mod +++ b/go-runtime/schema/testdata/fsm/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/fsm/go.sum b/go-runtime/schema/testdata/fsm/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/fsm/go.sum +++ b/go-runtime/schema/testdata/fsm/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/one/go.mod b/go-runtime/schema/testdata/one/go.mod index 7763d297af..33d7c3103c 100644 --- a/go-runtime/schema/testdata/one/go.mod +++ b/go-runtime/schema/testdata/one/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/one/go.sum b/go-runtime/schema/testdata/one/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/one/go.sum +++ b/go-runtime/schema/testdata/one/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/parent/go.mod b/go-runtime/schema/testdata/parent/go.mod index 24ee07a1d9..effb4395f9 100644 --- a/go-runtime/schema/testdata/parent/go.mod +++ b/go-runtime/schema/testdata/parent/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/parent/go.sum b/go-runtime/schema/testdata/parent/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/parent/go.sum +++ b/go-runtime/schema/testdata/parent/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/pubsub/go.mod b/go-runtime/schema/testdata/pubsub/go.mod index 9e1289cd7e..1cc90e2f41 100644 --- a/go-runtime/schema/testdata/pubsub/go.mod +++ b/go-runtime/schema/testdata/pubsub/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/pubsub/go.sum b/go-runtime/schema/testdata/pubsub/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/pubsub/go.sum +++ b/go-runtime/schema/testdata/pubsub/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/subscriber/go.mod b/go-runtime/schema/testdata/subscriber/go.mod index 35a7d9c389..31d5674483 100644 --- a/go-runtime/schema/testdata/subscriber/go.mod +++ b/go-runtime/schema/testdata/subscriber/go.mod @@ -36,13 +36,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/subscriber/go.sum b/go-runtime/schema/testdata/subscriber/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/subscriber/go.sum +++ b/go-runtime/schema/testdata/subscriber/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/two/go.mod b/go-runtime/schema/testdata/two/go.mod index df66aff063..3d275202bd 100644 --- a/go-runtime/schema/testdata/two/go.mod +++ b/go-runtime/schema/testdata/two/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/two/go.sum b/go-runtime/schema/testdata/two/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/two/go.sum +++ b/go-runtime/schema/testdata/two/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go-runtime/schema/testdata/validation/go.mod b/go-runtime/schema/testdata/validation/go.mod index 688040e8b0..5caa554e31 100644 --- a/go-runtime/schema/testdata/validation/go.mod +++ b/go-runtime/schema/testdata/validation/go.mod @@ -36,12 +36,12 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go-runtime/schema/testdata/validation/go.sum b/go-runtime/schema/testdata/validation/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/go-runtime/schema/testdata/validation/go.sum +++ b/go-runtime/schema/testdata/validation/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/go.mod b/go.mod index a9f790bb56..99b03db67c 100644 --- a/go.mod +++ b/go.mod @@ -49,9 +49,9 @@ require ( github.com/tink-crypto/tink-go-awskms v0.0.0-20230616072154-ba4f9f22c3e9 github.com/tink-crypto/tink-go/v2 v2.2.0 github.com/titanous/json5 v1.0.0 - github.com/tliron/commonlog v0.2.17 + github.com/tliron/commonlog v0.2.18 github.com/tliron/glsp v0.2.2 - github.com/tliron/kutil v0.3.24 + github.com/tliron/kutil v0.3.25 github.com/tmc/langchaingo v0.1.12 github.com/zalando/go-keyring v0.2.5 go.opentelemetry.io/otel v1.28.0 @@ -63,12 +63,12 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 go.uber.org/automaxprocs v1.5.3 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 - golang.org/x/mod v0.19.0 - golang.org/x/net v0.27.0 - golang.org/x/sync v0.7.0 - golang.org/x/term v0.22.0 + golang.org/x/mod v0.20.0 + golang.org/x/net v0.28.0 + golang.org/x/sync v0.8.0 + golang.org/x/term v0.23.0 google.golang.org/protobuf v1.34.2 - modernc.org/sqlite v1.31.1 + modernc.org/sqlite v1.32.0 ) require ( @@ -139,9 +139,9 @@ require ( github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b github.com/swaggest/refl v1.3.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/sys v0.22.0 - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/sys v0.24.0 + golang.org/x/text v0.17.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240709173604-40e1e62336c5 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect google.golang.org/grpc v1.65.0 // indirect diff --git a/go.sum b/go.sum index 062c7340c9..da82123bc5 100644 --- a/go.sum +++ b/go.sum @@ -256,12 +256,12 @@ github.com/tink-crypto/tink-go/v2 v2.2.0 h1:L2Da0F2Udh2agtKztdr69mV/KpnY3/lGTkMg github.com/tink-crypto/tink-go/v2 v2.2.0/go.mod h1:JJ6PomeNPF3cJpfWC0lgyTES6zpJILkAX0cJNwlS3xU= github.com/titanous/json5 v1.0.0 h1:hJf8Su1d9NuI/ffpxgxQfxh/UiBFZX7bMPid0rIL/7s= github.com/titanous/json5 v1.0.0/go.mod h1:7JH1M8/LHKc6cyP5o5g3CSaRj+mBrIimTxzpvmckH8c= -github.com/tliron/commonlog v0.2.17 h1:GFVvzDZbNLkuQfT45IZeWkrR5AyqiX7Du8pWAtFuPTY= -github.com/tliron/commonlog v0.2.17/go.mod h1:J2Hb63/mMjYmkDzd7E+VL9wCHT6NFNSzV/IOjJWMJqc= +github.com/tliron/commonlog v0.2.18 h1:F0zY09VDGTasPCpP9KvE8xqqVNMUfwMJQ0Xvo5Y6BRs= +github.com/tliron/commonlog v0.2.18/go.mod h1:7f3OMSgVyGAFbRKwlvfUErnB6U75LgW8wa6NlWuswGg= github.com/tliron/glsp v0.2.2 h1:IKPfwpE8Lu8yB6Dayta+IyRMAbTVunudeauEgjXBt+c= github.com/tliron/glsp v0.2.2/go.mod h1:GMVWDNeODxHzmDPvYbYTCs7yHVaEATfYtXiYJ9w1nBg= -github.com/tliron/kutil v0.3.24 h1:LvaqizF4htpEef9tC0B//sqtvQzEjDu69A4a1HrY+ko= -github.com/tliron/kutil v0.3.24/go.mod h1:2iSIhOnOe1reqczZQy6TauVHhItsq6xRLV2rVBvodpk= +github.com/tliron/kutil v0.3.25 h1:oaPN6K0zsH3KcVnsocA3kAlfR0XYDzADob6xdjqe56k= +github.com/tliron/kutil v0.3.25/go.mod h1:ZvOJuF6PTGvjfHmn2dFcgz+EDEzRQqQUztK+7djlXIw= github.com/tmc/langchaingo v0.1.12 h1:yXwSu54f3b1IKw0jJ5/DWu+qFVH1NBblwC0xddBzGJE= github.com/tmc/langchaingo v0.1.12/go.mod h1:cd62xD6h+ouk8k/QQFhOsjRYBSA1JJ5UVKXSIgm7Ni4= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= @@ -305,15 +305,15 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -321,14 +321,14 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -338,19 +338,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -403,8 +403,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/internal/encryption/testdata/go/encryption/go.mod b/internal/encryption/testdata/go/encryption/go.mod index 0eabab575f..f4fcecbdf1 100644 --- a/internal/encryption/testdata/go/encryption/go.mod +++ b/internal/encryption/testdata/go/encryption/go.mod @@ -34,13 +34,13 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/internal/encryption/testdata/go/encryption/go.sum b/internal/encryption/testdata/go/encryption/go.sum index 359cfad1d6..9fbb9ebc36 100644 --- a/internal/encryption/testdata/go/encryption/go.sum +++ b/internal/encryption/testdata/go/encryption/go.sum @@ -111,21 +111,21 @@ go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnC go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -140,8 +140,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/kotlin-runtime/ftl-runtime/pom.xml b/kotlin-runtime/ftl-runtime/pom.xml index ad9bdeef00..4a2e9c72d1 100644 --- a/kotlin-runtime/ftl-runtime/pom.xml +++ b/kotlin-runtime/ftl-runtime/pom.xml @@ -53,10 +53,10 @@ false 1.23.6 17 - 2.0.0 + 2.0.10 false 4.9.9 - 1.65.1 + 1.66.0 1.5.6 5.10.3 8.0 @@ -77,7 +77,7 @@ org.jetbrains.kotlin kotlin-reflect - 2.0.0 + 2.0.10 @@ -293,7 +293,7 @@ org.codehaus.mojo exec-maven-plugin - 3.3.0 + 3.4.0 wire-client diff --git a/kotlin-runtime/scaffolding/{{ .Name | lower }}/pom.xml b/kotlin-runtime/scaffolding/{{ .Name | lower }}/pom.xml index 92047d36e6..789035c48d 100644 --- a/kotlin-runtime/scaffolding/{{ .Name | lower }}/pom.xml +++ b/kotlin-runtime/scaffolding/{{ .Name | lower }}/pom.xml @@ -11,7 +11,7 @@ 1.0-SNAPSHOT 1.8 - 2.0.0 + 2.0.10 true ${java.version} ${java.version} diff --git a/rust-runtime/Cargo.lock b/rust-runtime/Cargo.lock index eef266182d..68f08b73a0 100644 --- a/rust-runtime/Cargo.lock +++ b/rust-runtime/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -235,9 +235,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.11" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36" dependencies = [ "clap_builder", "clap_derive", @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed" dependencies = [ "anstream", "anstyle", @@ -257,9 +257,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", @@ -1016,18 +1016,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", "memchr", From 412bb634e1f0bb45e8cb4c2eb58e9198be1d1502 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 00:12:14 +0000 Subject: [PATCH 07/35] chore(deps): update all non-major dependencies (#2314) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | Type | Update | |---|---|---|---|---|---|---|---| | [@codemirror/view](https://togithub.com/codemirror/view) | [`6.30.0` -> `6.31.0`](https://renovatebot.com/diffs/npm/@codemirror%2fview/6.30.0/6.31.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@codemirror%2fview/6.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@codemirror%2fview/6.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@codemirror%2fview/6.30.0/6.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@codemirror%2fview/6.30.0/6.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor | | [@types/node](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`20.14.14` -> `20.14.15`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.14/20.14.15) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/20.14.14/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/20.14.14/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch | | [clap](https://togithub.com/clap-rs/clap) | `4.5.14` -> `4.5.15` | [![age](https://developer.mend.io/api/mc/badges/age/crate/clap/4.5.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/clap/4.5.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/clap/4.5.14/4.5.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/clap/4.5.14/4.5.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [github.com/aws/aws-sdk-go](https://togithub.com/aws/aws-sdk-go) | `v1.44.267` -> `v1.55.5` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2faws%2faws-sdk-go/v1.55.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2faws%2faws-sdk-go/v1.55.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2faws%2faws-sdk-go/v1.44.267/v1.55.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2faws%2faws-sdk-go/v1.44.267/v1.55.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | require | minor | | [serde](https://serde.rs) ([source](https://togithub.com/serde-rs/serde)) | `1.0.205` -> `1.0.206` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde/1.0.206?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde/1.0.206?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde/1.0.205/1.0.206?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde/1.0.205/1.0.206?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [serde_json](https://togithub.com/serde-rs/json) | `1.0.122` -> `1.0.124` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde_json/1.0.124?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde_json/1.0.124?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde_json/1.0.122/1.0.124?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde_json/1.0.122/1.0.124?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | | [syn](https://togithub.com/dtolnay/syn) | `2.0.72` -> `2.0.74` | [![age](https://developer.mend.io/api/mc/badges/age/crate/syn/2.0.74?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/syn/2.0.74?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/syn/2.0.72/2.0.74?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/syn/2.0.72/2.0.74?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch | --- ### Release Notes
codemirror/view (@​codemirror/view) ### [`v6.31.0`](https://togithub.com/codemirror/view/blob/HEAD/CHANGELOG.md#6310-2024-08-11) [Compare Source](https://togithub.com/codemirror/view/compare/6.30.0...6.31.0) ##### Bug fixes Avoid the editor's geometry measurements becoming incorrect when fonts finish loading by scheduling a measure on `document.fonts.ready`. Avoid an issue where Chrome would incorrectly scroll the window when deleting lines in the editor. Fix an issue where in some layouts editor content would be drawn on top of panel elements. Fix an issue where `coordsAtPos` would return null when querying a position in a block widget. ##### New features The new `lineNumberWidgetMarker` facet makes it possible to insert markers into the line number gutter for widgets.
clap-rs/clap (clap) ### [`v4.5.15`](https://togithub.com/clap-rs/clap/blob/HEAD/CHANGELOG.md#4515---2024-08-10) [Compare Source](https://togithub.com/clap-rs/clap/compare/v4.5.14...v4.5.15) ##### Compatiblity - *(unstable-ext)* `Arg::remove` changed return types ##### Fixes - *(unstable-ext)* Make `Arg::remove` return the removed item
aws/aws-sdk-go (github.com/aws/aws-sdk-go) ### [`v1.55.5`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1555-2024-07-30) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.55.4...v1.55.5) \=== ##### Service Client Updates - `service/appstream`: Updates service API and documentation - Added support for Red Hat Enterprise Linux 8 on Amazon AppStream 2.0 - `service/autoscaling`: Updates service API and documentation - Increase the length limit for VPCZoneIdentifier from 2047 to 5000 - `service/codepipeline`: Updates service API, documentation, and paginators - AWS CodePipeline V2 type pipelines now support stage level conditions to enable development teams to safely release changes that meet quality and compliance requirements. - `service/elasticache`: Updates service documentation - Doc only update for changes to deletion API. - `service/elasticloadbalancing`: Updates service API - `service/eventbridge`: Updates service API - `service/logs`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/models.lex.v2`: Updates service API and documentation - `service/rolesanywhere`: Updates service API and documentation - `service/tnb`: Updates service API and documentation - `service/workspaces`: Updates service documentation - Removing multi-session as it isn't supported for pools ### [`v1.55.4`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1554-2024-07-29) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.55.3...v1.55.4) \=== ##### Service Client Updates - `service/elasticache`: Updates service documentation - Renaming full service name as it appears in developer documentation. - `service/memorydb`: Updates service API and documentation ### [`v1.55.3`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1553-2024-07-25) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.55.2...v1.55.3) \=== ##### Service Client Updates - `service/application-autoscaling`: Updates service API - `service/application-signals`: Updates service API and documentation - `service/bedrock-runtime`: Updates service API and documentation - `service/codecommit`: Updates service API and documentation - CreateRepository API now throws OperationNotAllowedException when the account has been restricted from creating a repository. - `service/datazone`: Updates service API and documentation - `service/ec2`: Updates service API and documentation - EC2 Fleet now supports using custom identifiers to reference Amazon Machine Images (AMI) in launch requests that are configured to choose from a diversified list of instance types. - `service/ecr`: Updates service API, documentation, paginators, and examples - API and documentation updates for Amazon ECR, adding support for creating, updating, describing and deleting ECR Repository Creation Template. - `service/eks`: Updates service API and documentation - `service/elasticloadbalancingv2`: Updates service API, documentation, and examples - `service/network-firewall`: Updates service API and documentation - `service/outposts`: Updates service API and documentation - `service/states`: Updates service API and documentation - This release adds support to customer managed KMS key encryption in AWS Step Functions. ##### SDK Bugs - Remove broken integration test. - Remove integration test broken by cloudsearch service. ### [`v1.55.2`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1552-2024-07-24) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.55.1...v1.55.2) \=== ##### Service Client Updates - `service/cleanrooms`: Updates service API and documentation - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - DynamoDB doc only update for July - `service/iotsitewise`: Updates service API and documentation - `service/mediapackagev2`: Updates service API - `service/medical-imaging`: Updates service API and documentation - `service/pinpoint-sms-voice-v2`: Updates service API and documentation ##### SDK Bugs - Add missing bool error matching. - This enables waiters defined to match on presence/absence of errors. ### [`v1.55.1`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1551-2024-07-23) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.55.0...v1.55.1) \=== ##### Service Client Updates - `service/appsync`: Updates service API and paginators - `service/cleanrooms`: Updates service API, documentation, and paginators - `service/cleanroomsml`: Updates service API, documentation, and waiters - `service/connect`: Updates service API and documentation - `service/connect-contact-lens`: Updates service API and documentation - `service/datazone`: Updates service API and documentation - `service/entityresolution`: Updates service API and documentation ### [`v1.55.0`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1550-2024-07-22) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.20...v1.55.0) \=== ##### Service Client Updates - `service/datazone`: Updates service API, documentation, and paginators - `service/ivs`: Updates service API and documentation - `service/redshift-serverless`: Updates service API and documentation ##### SDK Features - `service/mobile`: Remove Mobile - This change removes the Mobile service, which has been deprecated. ##### SDK Bugs - Apply sensitive struct tag to lists/maps with sensitive members. - This change propagates existing sensitive protection to lists/maps. ### [`v1.54.20`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15420-2024-07-18) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.19...v1.54.20) \=== ##### Service Client Updates - `service/acm-pca`: Updates service waiters - `service/connect`: Updates service API, documentation, and paginators - `service/ec2`: Updates service API and documentation - Amazon VPC IP Address Manager (IPAM) now supports Bring-Your-Own-IP (BYOIP) for IP addresses registered with any Internet Registry. This feature uses DNS TXT records to validate ownership of a public IP address range. - `service/firehose`: Updates service API and documentation - This release 1) Add configurable buffering hints for Snowflake as destination. 2) Add ReadFromTimestamp for MSK As Source. Firehose will start reading data from MSK Cluster using offset associated with this timestamp. 3) Gated public beta release to add Apache Iceberg tables as destination. - `service/ivschat`: Updates service API, documentation, and waiters - `service/medialive`: Updates service API and documentation - AWS Elemental MediaLive now supports the SRT protocol via the new SRT Caller input type. - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - Updates Amazon RDS documentation to specify an eventual consistency model for DescribePendingMaintenanceActions. - `service/sagemaker`: Updates service API - SageMaker Training supports R5, T3 and R5D instances family. And SageMaker Processing supports G5 and R5D instances family. - `service/secretsmanager`: Updates service documentation - Doc only update for Secrets Manager - `service/taxsettings`: Updates service API - `service/timestream-query`: Updates service API and documentation - `service/workspaces-thin-client`: Updates service API and documentation ### [`v1.54.19`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15419-2024-07-12) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.18...v1.54.19) \=== ##### Service Client Updates - `service/acm-pca`: Updates service API, documentation, waiters, and paginators - `service/arc-zonal-shift`: Updates service API and documentation - `service/autoscaling`: Adds new service - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/codebuild`: Adds new service - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/globalaccelerator`: Updates service API - `service/pinpoint`: Updates service API and documentation - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/quicksight`: Updates service API and documentation - Vega ally control options and Support for Reviewed Answers in Topics - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - Update path for CreateDBCluster resource identifier, and Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/sns`: Adds new service - Add v2 smoke tests and smithy smokeTests trait for SDK testing. ### [`v1.54.18`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15418-2024-07-10) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.17...v1.54.18) \=== ##### Service Client Updates - `service/batch`: Updates service API and documentation - This feature allows AWS Batch Jobs with EKS container orchestration type to be run as Multi-Node Parallel Jobs. - `service/bedrock`: Updates service API and documentation - `service/bedrock-agent`: Updates service API, documentation, and paginators - `service/bedrock-agent-runtime`: Updates service API, documentation, and paginators - `service/bedrock-runtime`: Updates service API and documentation - `service/ec2`: Updates service API and documentation - Add parameters to enable provisioning IPAM BYOIPv4 space at a Local Zone Network Border Group level - `service/glue`: Updates service API and documentation - Add recipe step support for recipe node - `service/groundstation`: Updates service API and documentation - `service/license-manager-linux-subscriptions`: Updates service API, documentation, and paginators - `service/mediaconnect`: Updates service API and documentation ### [`v1.54.17`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15417-2024-07-09) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.16...v1.54.17) \=== ##### Service Client Updates - `service/datazone`: Updates service API - `service/fsx`: Updates service API and documentation - `service/opensearch`: Updates service API and documentation - `service/sagemaker`: Updates service API, documentation, and paginators - This release 1/ enables optimization jobs that allows customers to perform Ahead-of-time compilation and quantization. 2/ allows customers to control access to Amazon Q integration in SageMaker Studio. 3/ enables AdditionalModelDataSources for CreateModel action. ### [`v1.54.16`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15416-2024-07-08) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.15...v1.54.16) \=== ##### Service Client Updates - `service/codedeploy`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/devicefarm`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/dms`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/elasticbeanstalk`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/email`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/es`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/firehose`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/gamelift`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/qapps`: Updates service API, documentation, waiters, paginators, and examples - `service/route53resolver`: Updates service API ### [`v1.54.15`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15415-2024-07-05) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.14...v1.54.15) \=== ##### Service Client Updates - `service/acm`: Updates service API and documentation - Documentation updates, including fixes for xml formatting, broken links, and ListCertificates description. - `service/ecr`: Updates service API - This release for Amazon ECR makes change to bring the SDK into sync with the API. - `service/payment-cryptography-data`: Updates service API and documentation - `service/qbusiness`: Updates service API and documentation ### [`v1.54.14`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15414-2024-07-03) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.13...v1.54.14) \=== ##### Service Client Updates - `service/application-autoscaling`: Updates service documentation - `service/directconnect`: Updates service documentation - This update includes documentation for support of new native 400 GBps ports for Direct Connect. - `service/organizations`: Updates service API and documentation - Added a new reason under ConstraintViolationException in RegisterDelegatedAdministrator API to prevent registering suspended accounts as delegated administrator of a service. - `service/rekognition`: Updates service API and documentation - This release adds support for tagging projects and datasets with the CreateProject and CreateDataset APIs. - `service/workspaces`: Updates service API - Fix create workspace bundle RootStorage/UserStorage to accept non null values ### [`v1.54.13`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15413-2024-07-02) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.12...v1.54.13) \=== ##### Service Client Updates - `service/ec2`: Updates service API and documentation - Documentation updates for Elastic Compute Cloud (EC2). - `service/fms`: Updates service API - `service/s3`: Updates service API, documentation, and examples - Added response overrides to Head Object requests. ### [`v1.54.12`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15412-2024-07-01) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.11...v1.54.12) \=== ##### Service Client Updates - `service/apigateway`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/cognito-identity`: Updates service API - `service/connect`: Updates service API, documentation, and paginators - `service/docdb`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/eks`: Updates service API - `service/payment-cryptography`: Updates service API and documentation - `service/payment-cryptography-data`: Updates service API, documentation, and waiters - `service/states`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/swf`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/wafv2`: Updates service API and documentation ### [`v1.54.11`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15411-2024-06-28) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.10...v1.54.11) \=== ##### Service Client Updates - `service/acm-pca`: Updates service API - `service/cloudhsmv2`: Updates service API and documentation - Added 3 new APIs to support backup sharing: GetResourcePolicy, PutResourcePolicy, and DeleteResourcePolicy. Added BackupArn to the output of the DescribeBackups API. Added support for BackupArn in the CreateCluster API. - `service/connect`: Updates service API and documentation - `service/elasticmapreduce`: Updates service API and documentation - This release provides the support for new allocation strategies i.e. CAPACITY_OPTIMIZED_PRIORITIZED for Spot and PRIORITIZED for On-Demand by taking input of priority value for each instance type for instance fleet clusters. - `service/glue`: Updates service API and documentation - Added AttributesToGet parameter to Glue GetDatabases, allowing caller to limit output to include only the database name. - `service/kinesisanalyticsv2`: Updates service API and documentation - `service/opensearch`: Updates service API and documentation - `service/pi`: Updates service API and documentation - `service/workspaces`: Updates service API and documentation - Added support for Red Hat Enterprise Linux 8 on Amazon WorkSpaces Personal. ### [`v1.54.10`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15410-2024-06-27) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.9...v1.54.10) \=== ##### Service Client Updates - `service/application-autoscaling`: Updates service API and documentation - `service/chime-sdk-media-pipelines`: Updates service API and documentation - `service/cloudfront`: Updates service API and documentation - Doc only update for CloudFront that fixes customer-reported issue - `service/datazone`: Updates service API, documentation, and paginators - `service/elasticache`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/mq`: Updates service API and documentation - This release makes the EngineVersion field optional for both broker and configuration and uses the latest available version by default. The AutoMinorVersionUpgrade field is also now optional for broker creation and defaults to 'true'. - `service/qconnect`: Updates service API, documentation, and paginators - `service/quicksight`: Updates service API and documentation - Adding support for Repeating Sections, Nested Filters - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - Updates Amazon RDS documentation for TAZ export to S3. - `service/sagemaker`: Updates service API and documentation - Add capability for Admins to customize Studio experience for the user by showing or hiding Apps and MLTools. - `service/workspaces`: Updates service API and documentation - Added support for WorkSpaces Pools. ### [`v1.54.9`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1549-2024-06-26) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.8...v1.54.9) \=== ##### Service Client Updates - `service/controltower`: Updates service API, documentation, and paginators - `service/eks`: Updates service API and documentation - `service/ivs-realtime`: Updates service API, documentation, and paginators - `service/kinesisanalyticsv2`: Updates service API, documentation, and paginators - `service/opensearch`: Updates service API and documentation ### [`v1.54.8`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1548-2024-06-25) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.7...v1.54.8) \=== ##### Service Client Updates - `service/autoscaling`: Updates service API and documentation - Doc only update for Auto Scaling's TargetTrackingMetricDataQuery - `service/ec2`: Updates service API - This release is for the launch of the new u7ib-12tb.224xlarge, R8g, c7gn.metal and mac2-m1ultra.metal instance types - `service/networkmanager`: Updates service API and documentation - `service/workspaces-thin-client`: Updates service API and documentation ### [`v1.54.7`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1547-2024-06-24) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.6...v1.54.7) \=== ##### Service Client Updates - `service/bedrock-runtime`: Updates service API - `service/customer-profiles`: Updates service API and documentation - `service/ec2`: Updates service API - Fix EC2 multi-protocol info in models. - `service/qbusiness`: Updates service API and documentation - `service/ssm`: Updates service API - Add sensitive trait to SSM IPAddress property for CloudTrail redaction - `service/workspaces-web`: Updates service API and documentation ### [`v1.54.6`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1546-2024-06-20) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.5...v1.54.6) \=== ##### Service Client Updates - `service/bedrock-runtime`: Updates service API and documentation - `service/codeartifact`: Updates service API and documentation - `service/compute-optimizer`: Updates service API and documentation - `service/cost-optimization-hub`: Updates service API, documentation, and waiters - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - Doc-only update for DynamoDB. Fixed Important note in 6 Global table APIs - CreateGlobalTable, DescribeGlobalTable, DescribeGlobalTableSettings, ListGlobalTables, UpdateGlobalTable, and UpdateGlobalTableSettings. - `service/glue`: Updates service paginators - Fix Glue paginators for Jobs, JobRuns, Triggers, Blueprints and Workflows. - `service/ivs-realtime`: Updates service API, documentation, and waiters - `service/sagemaker`: Updates service API and documentation - Adds support for model references in Hub service, and adds support for cross-account access of Hubs - `service/securityhub`: Updates service API and documentation ### [`v1.54.5`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1545-2024-06-19) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.4...v1.54.5) \=== ##### Service Client Updates - `service/artifact`: Updates service API, documentation, waiters, and examples - `service/athena`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/cur`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/directconnect`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/elastictranscoder`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/opensearch`: Updates service API and documentation ### [`v1.54.4`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1544-2024-06-18) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.3...v1.54.4) \=== ##### Service Client Updates - `service/bedrock-runtime`: Updates service API and documentation - `service/cloudtrail`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/config`: Updates service API - `service/eks`: Updates service API and documentation - `service/lightsail`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/polly`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/rekognition`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/sagemaker`: Updates service API, documentation, and paginators - Launched a new feature in SageMaker to provide managed MLflow Tracking Servers for customers to track ML experiments. This release also adds a new capability of attaching additional storage to SageMaker HyperPod cluster instances. - `service/shield`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/snowball`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. ### [`v1.54.3`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1543-2024-06-17) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.2...v1.54.3) \=== ##### Service Client Updates - `service/acm-pca`: Updates service API and documentation - `service/batch`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/codebuild`: Updates service API and documentation - AWS CodeBuild now supports global and organization GitHub webhooks - `service/cognito-idp`: Updates service API - `service/ds`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/elasticfilesystem`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/glue`: Updates service API, documentation, and paginators - This release introduces a new feature, Usage profiles. Usage profiles allow the AWS Glue admin to create different profiles for various classes of users within the account, enforcing limits and defaults for jobs and sessions. - `service/kms`: Updates service examples - Updating SDK example for KMS DeriveSharedSecret API. - `service/mediaconvert`: Updates service API and documentation - This release includes support for creating I-frame only video segments for DASH trick play. - `service/secretsmanager`: Updates service documentation - Doc only update for Secrets Manager - `service/waf`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. ### [`v1.54.2`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1542-2024-06-14) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.1...v1.54.2) \=== ##### Service Client Updates - `service/datazone`: Updates service API, documentation, and paginators - `service/ec2`: Updates service documentation - Documentation updates for Amazon EC2. - `service/macie2`: Updates service API, documentation, and paginators - `service/mediaconvert`: Updates service API, documentation, and paginators - This release adds the ability to search for historical job records within the management console using a search box and/or via the SDK/CLI with partial string matching search on input file name. - `service/route53domains`: Updates service API - Add v2 smoke tests and smithy smokeTests trait for SDK testing. ##### SDK Bugs - Remove test dependency on golang.org/x/net. - This was used for h2 support which is now transparently available in the stdlib. ### [`v1.54.1`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1541-2024-06-13) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.54.0...v1.54.1) \=== ##### Service Client Updates - `service/cloudhsmv2`: Updates service API and documentation - Added support for hsm type hsm2m.medium. Added supported for creating a cluster in FIPS or NON_FIPS mode. - `service/glue`: Updates service API and documentation - This release adds support for configuration of evaluation method for composite rules in Glue Data Quality rulesets. - `service/iotwireless`: Updates service API - `service/kms`: Updates service API, documentation, and examples - This feature allows customers to use their keys stored in KMS to derive a shared secret which can then be used to establish a secured channel for communication, provide proof of possession, or establish trust with other parties. - `service/mediapackagev2`: Updates service API, documentation, and examples ### [`v1.54.0`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1540-2024-06-12) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.21...v1.54.0) \=== ##### Service Client Updates - `service/apptest`: Updates service API, documentation, waiters, paginators, and examples - `service/ec2`: Updates service API and documentation - Tagging support for Traffic Mirroring FilterRule resource - `service/osis`: Updates service API and documentation - `service/redshift`: Updates service API and documentation - Updates to remove DC1 and DS2 node types. - `service/secretsmanager`: Updates service API and documentation - Introducing RotationToken parameter for PutSecretValue API - `service/securitylake`: Updates service API and documentation - `service/sesv2`: Updates service API and documentation ##### SDK Features - `service/backupstorage`: Remove Backupstorage - This change removes the Backupstorage service, which has been deprecated. ### [`v1.53.21`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15321-2024-06-11) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.20...v1.53.21) \=== ##### Service Client Updates - `service/accessanalyzer`: Updates service API, documentation, paginators, and examples - `service/guardduty`: Updates service API and documentation - Added API support for GuardDuty Malware Protection for S3. - `service/networkmanager`: Updates service API and documentation - `service/pca-connector-scep`: Adds new service - `service/sagemaker`: Updates service API and documentation - Introduced Scope and AuthenticationRequestExtraParams to SageMaker Workforce OIDC configuration; this allows customers to modify these options for their private Workforce IdP integration. Model Registry Cross-account model package groups are discoverable. ### [`v1.53.20`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15320-2024-06-10) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.19...v1.53.20) \=== ##### Service Client Updates - `service/application-signals`: Adds new service - `service/ecs`: Updates service API and documentation - This release introduces a new cluster configuration to support the customer-managed keys for ECS managed storage encryption. - `service/imagebuilder`: Updates service API ### [`v1.53.19`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15319-2024-06-07) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.18...v1.53.19) \=== ##### Service Client Updates - `service/auditmanager`: Updates service API and documentation - `service/b2bi`: Updates service API - `service/codepipeline`: Updates service API and documentation - CodePipeline now supports overriding S3 Source Object Key during StartPipelineExecution, as part of Source Overrides. - `service/sagemaker`: Updates service API and documentation - This release introduces a new optional parameter: InferenceAmiVersion, in ProductionVariant. - `service/verifiedpermissions`: Updates service API and documentation ### [`v1.53.18`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15318-2024-06-06) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.17...v1.53.18) \=== ##### Service Client Updates - `service/account`: Updates service API and documentation - `service/firehose`: Updates service API and documentation - Adds integration with Secrets Manager for Redshift, Splunk, HttpEndpoint, and Snowflake destinations - `service/fsx`: Updates service API and documentation - `service/glue`: Updates service API and documentation - This release adds support for creating and updating Glue Data Catalog Views. - `service/iotwireless`: Updates service API - `service/location`: Updates service API, documentation, and paginators - `service/sns`: Updates service API and documentation - Doc-only update for SNS. These changes include customer-reported issues and TXC3 updates. - `service/sqs`: Updates service API and documentation - Doc only updates for SQS. These updates include customer-reported issues and TCX3 modifications. - `service/storagegateway`: Updates service API and documentation - Adds SoftwareUpdatePreferences to DescribeMaintenanceStartTime and UpdateMaintenanceStartTime, a structure which contains AutomaticUpdatePolicy. ### [`v1.53.17`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15317-2024-06-05) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.16...v1.53.17) \=== ##### Service Client Updates - `service/globalaccelerator`: Updates service API and documentation - `service/glue`: Updates service API and documentation - AWS Glue now supports native SaaS connectivity: Salesforce connector available now - `service/s3`: Updates service API and examples - Added new params copySource and key to copyObject API for supporting S3 Access Grants plugin. These changes will not change any of the existing S3 API functionality. ### [`v1.53.16`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15316-2024-06-04) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.15...v1.53.16) \=== ##### Service Client Updates - `service/ec2`: Updates service API - U7i instances with up to 32 TiB of DDR5 memory and 896 vCPUs are now available. C7i-flex instances are launched and are lower-priced variants of the Amazon EC2 C7i instances that offer a baseline level of CPU performance with the ability to scale up to the full compute performance 95% of the time. - `service/pipes`: Updates service API, documentation, and waiters - `service/sagemaker`: Updates service API and documentation - Extend DescribeClusterNode response with private DNS hostname and IP address, and placement information about availability zone and availability zone ID. - `service/taxsettings`: Adds new service ### [`v1.53.15`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15315-2024-06-03) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.14...v1.53.15) \=== ##### Service Client Updates - `service/amplify`: Updates service documentation - `service/batch`: Updates service API and documentation - This release adds support for the AWS Batch GetJobQueueSnapshot API operation. - `service/eks`: Updates service API and documentation - `service/iottwinmaker`: Updates service API ### [`v1.53.14`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15314-2024-05-31) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.13...v1.53.14) \=== ##### Service Client Updates - `service/codebuild`: Updates service documentation - AWS CodeBuild now supports Self-hosted GitHub Actions runners for Github Enterprise - `service/codeguru-security`: Updates service API and documentation - `service/elasticache`: Updates service API and documentation - Update to attributes of TestFailover and minor revisions. - `service/launch-wizard`: Updates service API and documentation ### [`v1.53.13`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15313-2024-05-30) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.12...v1.53.13) \=== ##### Service Client Updates - `service/acm`: Updates service API - add v2 smoke tests and smithy smokeTests trait for SDK testing. - `service/bedrock-agent`: Updates service API and documentation - `service/bedrock-runtime`: Updates service API and documentation - `service/cloudtrail`: Updates service API and documentation - CloudTrail Lake returns PartitionKeys in the GetEventDataStore API response. Events are grouped into partitions based on these keys for better query performance. For example, the calendarday key groups events by day, while combining the calendarday key with the hour key groups them by day and hour. - `service/connect`: Updates service API and documentation - `service/emr-serverless`: Updates service API, documentation, and paginators - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - Updates Amazon RDS documentation for Aurora Postgres DBname. - `service/sagemaker`: Updates service API and documentation - Adds Model Card information as a new component to Model Package. Autopilot launches algorithm selection for TimeSeries modality to generate AutoML candidates per algorithm. ### [`v1.53.12`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15312-2024-05-29) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.11...v1.53.12) \=== ##### Service Client Updates - `service/athena`: Updates service API and documentation - Throwing validation errors on CreateNotebook with Name containing `/`,`:`,`\` - `service/codebuild`: Updates service API and documentation - AWS CodeBuild now supports manually creating GitHub webhooks - `service/connect`: Updates service API and documentation - `service/glue`: Updates service API and documentation - Add optional field JobMode to CreateJob and UpdateJob APIs. - `service/securityhub`: Updates service API ### [`v1.53.11`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15311-2024-05-28) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.10...v1.53.11) \=== ##### Service Client Updates - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - Doc-only update for DynamoDB. Specified the IAM actions needed to authorize a user to create a table with a resource-based policy. - `service/ec2`: Updates service API and documentation - Providing support to accept BgpAsnExtended attribute - `service/kafka`: Updates service API and documentation - `service/swf`: Updates service API and documentation - This release adds new APIs for deleting activity type and workflow type resources. ### [`v1.53.10`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15310-2024-05-24) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.9...v1.53.10) \=== ##### Service Client Updates - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - Documentation only updates for DynamoDB. - `service/iotfleetwise`: Updates service API and documentation - `service/managedblockchain`: Updates service API and documentation ##### SDK Bugs - Fix misaligned struct member used in atomic operation. - This change fixes panics on 32-bit systems in services that use endpoint discovery. ### [`v1.53.9`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1539-2024-05-23) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.8...v1.53.9) \=== ##### Service Client Updates - `service/emr-serverless`: Updates service API and documentation - `service/opsworks`: Updates service API and documentation - Documentation-only update for OpsWorks Stacks. ### [`v1.53.8`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1538-2024-05-22) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.7...v1.53.8) \=== ##### Service Client Updates - `service/chatbot`: Updates service API and documentation - `service/cloudformation`: Updates service API and documentation - Added DeletionMode FORCE_DELETE_STACK for deleting a stack that is stuck in DELETE_FAILED state due to resource deletion failure. - `service/kms`: Updates service API and documentation - This release includes feature to import customer's asymmetric (RSA, ECC and SM2) and HMAC keys into KMS in China. - `service/opensearch`: Updates service API and documentation - `service/wafv2`: Updates service API and documentation ##### SDK Bugs - `service/ec2`: Correct empty list serialization behavior. - Empty, non-nil lists should NOT be serialized for this service. ### [`v1.53.7`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1537-2024-05-21) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.6...v1.53.7) \=== ##### Service Client Updates - `service/cloudfront`: Updates service API - Model update; no change to SDK functionality. - `service/glue`: Updates service API and documentation - Add Maintenance window to CreateJob and UpdateJob APIs and JobRun response. Add a new Job Run State for EXPIRED. - `service/lightsail`: Updates service API and documentation - This release adds support for Amazon Lightsail instances to switch between dual-stack or IPv4 only and IPv6-only public IP address types. - `service/mailmanager`: Adds new service - `service/pi`: Updates service API and documentation - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - Updates Amazon RDS documentation for Db2 license through AWS Marketplace. - `service/storagegateway`: Updates service API and documentation - Added new SMBSecurityStrategy enum named MandatoryEncryptionNoAes128, new mode enforces encryption and disables AES 128-bit algorithums. ### [`v1.53.6`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1536-2024-05-20) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.5...v1.53.6) \=== ##### Service Client Updates - `service/bedrock-agent`: Updates service API and documentation - `service/bedrock-agent-runtime`: Updates service API and documentation - `service/controltower`: Updates service API, documentation, and paginators - `service/osis`: Updates service API and documentation - `service/rds`: Updates service API, documentation, waiters, paginators, and examples - This release adds support for EngineLifecycleSupport on DBInstances, DBClusters, and GlobalClusters. - `service/secretsmanager`: Updates service documentation - add v2 smoke tests and smithy smokeTests trait for SDK testing ### [`v1.53.5`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1535-2024-05-17) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.4...v1.53.5) \=== ##### Service Client Updates - `service/application-autoscaling`: Updates service API - `service/codebuild`: Updates service API and documentation - Aws CodeBuild now supports 36 hours build timeout - `service/elasticloadbalancingv2`: Updates service API and documentation - `service/lakeformation`: Updates service API and documentation - `service/transfer`: Updates service API and documentation - Enable use of CloudFormation traits in Smithy model to improve generated CloudFormation schema from the Smithy API model. ### [`v1.53.4`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1534-2024-05-16) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.3...v1.53.4) \=== ##### Service Client Updates - `service/acm-pca`: Updates service API and waiters - `service/connect`: Updates service documentation - `service/kafka`: Updates service API and documentation - `service/mwaa`: Updates service API and documentation - `service/quicksight`: Updates service API and documentation - This release adds DescribeKeyRegistration and UpdateKeyRegistration APIs to manage QuickSight Customer Managed Keys (CMK). - `service/sagemaker`: Updates service API and documentation - Introduced WorkerAccessConfiguration to SageMaker Workteam. This allows customers to configure resource access for workers in a workteam. - `service/secretsmanager`: Updates service API and documentation - Documentation updates for AWS Secrets Manager ### [`v1.53.3`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1533-2024-05-15) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.2...v1.53.3) \=== ##### Service Client Updates - `service/bedrock-agent-runtime`: Updates service documentation - `service/codebuild`: Updates service API and documentation - CodeBuild Reserved Capacity VPC Support - `service/datasync`: Updates service API - `service/grafana`: Updates service API, documentation, and paginators - `service/medical-imaging`: Updates service API and documentation - `service/securityhub`: Updates service API and documentation ### [`v1.53.2`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1532-2024-05-14) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.1...v1.53.2) \=== ##### Service Client Updates - `service/connect`: Updates service API, documentation, and paginators - `service/s3`: Updates service API and examples - Updated a few x-id in the http uri traits ### [`v1.53.1`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1531-2024-05-13) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.53.0...v1.53.1) \=== ##### Service Client Updates - `service/eventbridge`: Updates service API and documentation - `service/vpc-lattice`: Updates service API and documentation ### [`v1.53.0`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1530-2024-05-10) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.6...v1.53.0) \=== ##### Service Client Updates - `service/discovery`: Updates service API - add v2 smoke tests and smithy smokeTests trait for SDK testing - `service/greengrassv2`: Updates service API and documentation - `service/sagemaker`: Updates service API - Introduced support for G6 instance types on Sagemaker Notebook Instances and on SageMaker Studio for JupyterLab and CodeEditor applications. - `service/sso-oidc`: Updates service API, documentation, and examples ##### SDK Features - `service/honeycode`: Remove Honeycode - This change removes the Honeycode service, which has been deprecated. ### [`v1.52.6`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1526-2024-05-09) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.5...v1.52.6) \=== ##### Service Client Updates - `service/bedrock-agent-runtime`: Updates service API and documentation - `service/pinpoint`: Updates service API and documentation - This release adds support for specifying email message headers for Email Templates, Campaigns, Journeys and Send Messages. - `service/route53resolver`: Updates service documentation - `service/ssm-sap`: Updates service API, documentation, and paginators - `service/verifiedpermissions`: Updates service API and documentation ### [`v1.52.5`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1525-2024-05-08) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.4...v1.52.5) \=== ##### Service Client Updates - `service/cognito-idp`: Updates service API - `service/ec2`: Updates service API and documentation - Adding Precision Hardware Clock (PHC) to public API DescribeInstanceTypes - `service/ecr`: Updates service API and documentation - This release adds pull through cache rules support for GitLab container registry in Amazon ECR. - `service/fms`: Updates service documentation - `service/polly`: Updates service API and documentation - Add new engine - generative - that builds the most expressive conversational voices. - `service/sqs`: Updates service API and documentation - This release adds MessageSystemAttributeNames to ReceiveMessageRequest to replace AttributeNames. ### [`v1.52.4`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1524-2024-05-07) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.3...v1.52.4) \=== ##### Service Client Updates - `service/b2bi`: Updates service documentation - `service/budgets`: Updates service API and documentation - This release adds tag support for budgets and budget actions. - `service/resiliencehub`: Updates service API, documentation, and paginators - `service/route53profiles`: Updates service API and documentation ### [`v1.52.3`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1523-2024-05-06) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.2...v1.52.3) \=== ##### Service Client Updates - `service/medialive`: Updates service API and documentation - AWS Elemental MediaLive now supports configuring how SCTE 35 passthrough triggers segment breaks in HLS and MediaPackage output groups. Previously, messages triggered breaks in all these output groups. The new option is to trigger segment breaks only in groups that have SCTE 35 passthrough enabled. ### [`v1.52.2`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1522-2024-05-03) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.1...v1.52.2) \=== ##### Service Client Updates - `service/bedrock-agent`: Updates service API and documentation - `service/connect`: Updates service API and documentation - `service/connectcases`: Updates service API and documentation - `service/datasync`: Updates service API and documentation - `service/inspector2`: Updates service API and documentation - `service/sagemaker`: Updates service API and documentation - Amazon SageMaker Inference now supports m6i, c6i, r6i, m7i, c7i, r7i and g5 instance types for Batch Transform Jobs - `service/sesv2`: Updates service API and documentation ### [`v1.52.1`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1521-2024-05-02) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.52.0...v1.52.1) \=== ##### Service Client Updates - `service/dynamodb`: Updates service API, documentation, waiters, paginators, and examples - This release adds support to specify an optional, maximum OnDemandThroughput for DynamoDB tables and global secondary indexes in the CreateTable or UpdateTable APIs. You can also override the OnDemandThroughput settings by calling the ImportTable, RestoreFromPointInTime, or RestoreFromBackup APIs. - `service/ec2`: Updates service API and documentation - This release includes a new API for retrieving the public endorsement key of the EC2 instance's Nitro Trusted Platform Module (NitroTPM). - `service/personalize`: Updates service API and documentation - `service/redshift-serverless`: Updates service API and documentation ### [`v1.52.0`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v1520-2024-05-01) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.51.32...v1.52.0) \=== ##### Service Client Updates - `service/bedrock-agent`: Updates service API and documentation - `service/ec2`: Updates service documentation - Documentation updates for Amazon EC2. - `service/personalize-runtime`: Updates service API and documentation - `service/securityhub`: Updates service API and documentation - `service/sesv2`: Updates service API ##### SDK Features - `service/alexaforbusiness`: Remove Alexaforbusiness - This change removes the Alexaforbusiness service, since it is deprecated. ### [`v1.51.32`](https://togithub.com/aws/aws-sdk-go/blob/HEAD/CHANGELOG.md#Release-v15132-2024-04-30) [Compare Source](https://togithub.com/aws/aws-sdk-go/compare/v1.51.31...v1.51.32) \=== ##### Service Client Updates - `service/chime-sdk-voice`: Updates service API and documentation - `service/codeartifact`: Updates service API and documentation - `service/fms`: Updates service API and documentation - `service/omics`: Updates service API and documentation - `service/opensearch`: Updates service API and documentation - `service/pinpoint-sms-voice-v2`: Updates service API, documentation, and paginators - `service/qbusiness`: Updates service API, documentation, and waiters - `service/quicksight`: Updates service API and documentation - New Q embedding supporting Generative Q\&A - `service/route53resolver`: Updates service API and documentation - `service/sagemaker`: Updates service API and documentation - Amazon SageMaker Training now supports the use of attribute-based access control (ABAC) roles for training job execution roles. Amazon SageMaker Inference now supports G6 instance types. - `service/signer`: Updates service API and documentation
--- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/TBD54566975/ftl). --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- extensions/vscode/package-lock.json | 6 +++--- frontend/package-lock.json | 6 +++--- go.mod | 2 +- go.sum | 22 ++-------------------- rust-runtime/Cargo.lock | 24 ++++++++++++------------ 5 files changed, 21 insertions(+), 39 deletions(-) diff --git a/extensions/vscode/package-lock.json b/extensions/vscode/package-lock.json index e0a6e3cfa5..97667b1f4a 100644 --- a/extensions/vscode/package-lock.json +++ b/extensions/vscode/package-lock.json @@ -599,9 +599,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", - "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "version": "20.14.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", + "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index abba6a30d5..ed6e3ffafd 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2280,9 +2280,9 @@ "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" }, "node_modules/@codemirror/view": { - "version": "6.30.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.30.0.tgz", - "integrity": "sha512-96Nmn8OeLh6aONQprIeYk8hGVnEuYpWuxKSkdsODOx9hWPxyuyZGvmvxV/JmLsp+CubMO1PsLaN5TNNgrl0UrQ==", + "version": "6.31.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.31.0.tgz", + "integrity": "sha512-pEqRyzcodpvIuWOhGSo0AIs3WKnewDl1EffAnaSZjqGtxk8HisBLY3VltYKA6Lr94VBH3B6O7G8G1tsQ/Wyi7w==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.4.0", diff --git a/go.mod b/go.mod index 99b03db67c..229522885f 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/alecthomas/participle/v2 v2.1.1 github.com/alecthomas/types v0.16.0 github.com/amacneil/dbmate/v2 v2.19.0 - github.com/aws/aws-sdk-go v1.44.267 + github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go-v2 v1.30.3 github.com/aws/aws-sdk-go-v2/config v1.27.27 github.com/aws/aws-sdk-go-v2/credentials v1.17.27 diff --git a/go.sum b/go.sum index da82123bc5..93f56bfac0 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4u github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/amacneil/dbmate/v2 v2.19.0 h1:RqqkBv6/Jbupuv8GcpBXNdRdSjocddiwmfE56Oil6YA= github.com/amacneil/dbmate/v2 v2.19.0/go.mod h1:zyIkE4QZ+C+NxX0YNDb6zYlmEzCXMU7SGyYrtAJVDEk= -github.com/aws/aws-sdk-go v1.44.267 h1:Asrp6EMqqRxZvjK0NjzkWcrOk15RnWtupuUrUuZMabk= -github.com/aws/aws-sdk-go v1.44.267/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= @@ -270,7 +270,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= @@ -304,51 +303,35 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -357,7 +340,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/rust-runtime/Cargo.lock b/rust-runtime/Cargo.lock index 68f08b73a0..a51291798b 100644 --- a/rust-runtime/Cargo.lock +++ b/rust-runtime/Cargo.lock @@ -235,9 +235,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.14" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36" +checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" dependencies = [ "clap_builder", "clap_derive", @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.14" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -1016,18 +1016,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.205" +version = "1.0.206" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" +checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.205" +version = "1.0.206" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" +checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97" dependencies = [ "proc-macro2", "quote", @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", "memchr", @@ -1088,9 +1088,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.72" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", From ca0922f871509e4ddedf9ad64873684e77e24691 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Mon, 12 Aug 2024 10:20:17 +1000 Subject: [PATCH 08/35] docs: update code review policy (#2313) --- CONTRIBUTING.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 990e03fba2..42c509c032 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,9 +12,11 @@ This guide is for you. ## Development Prerequisites We recommend that you use OrbStack instead of Docker desktop when developing on this project: + ``` brew install orbstack ``` + or [OrbStack Website](https://orbstack.dev/) The tools used by this project are managed by @@ -56,9 +58,18 @@ $ ftl dev --recreate ./examples/go ### Code reviews -Because we're a geographically distributed team, we use a review-after-merge development flow. That is, if a PR is urgent, minor, or the developer has high confidence, we encourage merging without waiting for review in order to decrease friction. Conversely, if a change is more complex, or needs more eyes, we encourage developers to wait for review if it will make them feel more comfortable. Use your best judgement. +Our goal is to maintain velocity while keeping code quality high. To that end, the process is an exercise in trust on the part of the reviewer, and responsibility on the part of the PR author. + +In practice, the **reviewer** will review _and_ approve the PR at the same time, trusting that the author will apply the feedback before merging. + +On the **author's** side, they are responsible for reading and understanding all feedback, and applying that feedback where they think it is appropriate. If either side doesn't understand something and it's important, comment accordingly, or do a quick pairing to resolve it. The author should feel free to re-request a review. + +Additional points of note: -We discourage bike-shedding. Code and documentation are easy to change, we can always adjust it later. +- We discourage bike-shedding. Code and documentation are easy to change, we can always adjust it later. +- Keep your PRs digestible, large PRs are very difficult to comprehend and review. +- Changing code is cheap, we can fix it later. The only caveat here is data storage. +- Reviewing code is everybody's responsibility. ### Design process @@ -135,6 +146,7 @@ just build-sqlc ``` We use [dbmate](https://github.com/amacneil/dbmate) to manage migrations. To create a migration file, run `dbmate new` with the name of your migration. Example: + ``` dbmate new create_users_table ``` @@ -191,15 +203,19 @@ For an in-line replacement of `ftl dev `, use the command: just debug ``` -This command compiles a binary with debug information, runs `ftl dev ` using this binary, and provides an endpoint to attach a remote debugger at __127.0.0.1:2345__. +This command compiles a binary with debug information, runs `ftl dev ` using this binary, and provides an endpoint to attach a remote debugger at **127.0.0.1:2345**. You do not need to run `FTL_DEBUG=true just build ftl` separately when using this command. + ### Attaching a Debugger By running `just debug ` and then attaching a remote debugger, you can debug the FTL infrastructure while running your project. #### IntelliJ + Run `Debug FTL` from the `Run/Debug Configurations` dropdown while in the FTL project. + #### VSCode + Run `Debug FTL` from the `Run and Debug` dropdown while in the FTL project. ## Useful links From b59eba3f8e90e2d69b298a4c650a27cebbe7d7e1 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 12 Aug 2024 12:12:58 +1000 Subject: [PATCH 09/35] chore: retry npm install on failure (#2320) --- Justfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Justfile b/Justfile index ebdc6a56c3..01acf1b203 100644 --- a/Justfile +++ b/Justfile @@ -107,9 +107,10 @@ build-kt-runtime: @cd build/template && zip -q --symlinks -r ../../{{RUNNER_TEMPLATE_ZIP}} . # Install Node dependencies +# npm install fails intermittently due to network issues, so we retry a few times. npm-install: - @mk frontend/node_modules : frontend/package.json -- "cd frontend && npm install" - @mk extensions/vscode/node_modules : extensions/vscode/package.json extensions/vscode/src -- "cd extensions/vscode && npm install" + @mk frontend/node_modules : frontend/package.json -- "cd frontend && for i in {1..3}; do npm install && break || sleep 5; done" + @mk extensions/vscode/node_modules : extensions/vscode/package.json extensions/vscode/src -- "cd extensions/vscode && for i in {1..3}; do npm install && break || sleep 5; done" # Regenerate protos build-protos: npm-install From d6d432d932e50b315708a775a44715a70a5800e2 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 12 Aug 2024 12:24:55 +1000 Subject: [PATCH 10/35] chore: update OpenJDK renovate config (#2319) --- renovate.json5 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index e5b258894b..2da4c874b5 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -24,6 +24,14 @@ matchManagers: ["hermit"], enabled: false, }, + { + matchPackageNames: [ + "openjdk", // We don't want automatic major version updates, just minors + ], + matchManagers: ["hermit"], + matchUpdateTypes: ["major"], + enabled: false + }, { matchFileNames: ["**/testdata/**/go.mod"], enabled: false, From 1fa898fdd517f7b9956c4afd6398fcd2d581c0f8 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 12 Aug 2024 12:30:28 +1000 Subject: [PATCH 11/35] fix: don't log at error level in lease timeout (#2151) We don't want error alerts if a controller is just failing over, this PR adds some infrasturcture to allow for a lower level of error reporting when the errors all occur within the lease TTL. fixes #2133 --- backend/controller/leader/leader.go | 68 ++++++++++++++++++++++++ backend/controller/leader/leader_test.go | 27 ++++++++++ common/configuration/asm.go | 21 ++++---- common/configuration/asm_follower.go | 26 ++++++--- common/configuration/asm_test.go | 3 +- 5 files changed, 127 insertions(+), 18 deletions(-) diff --git a/backend/controller/leader/leader.go b/backend/controller/leader/leader.go index a12b6f018a..643adc327e 100644 --- a/backend/controller/leader/leader.go +++ b/backend/controller/leader/leader.go @@ -220,3 +220,71 @@ func (c *Coordinator[P]) retireFollower() { f.cancelCtx() c.follower = optional.None[*follower[P]]() } + +// ErrorFilter allows uses of leases to decide if an error might be due to the master falling over, +// or is something else that will not resolve itself after the TTL +type ErrorFilter struct { + leaseTTL time.Duration + // Error reporting utilities + // If a controller has failed over we don't want error logs while we are waiting for the lease to expire. + // This records error state and allows us to filter errors until we are past lease timeout + // and only reports the error if it persists + // firstErrorTime is the time of the first error, used to lower log levels if the errors all occur within a lease window + firstErrorTime optional.Option[time.Time] + recordedSuccessTime optional.Option[time.Time] + + // errorMutex protects firstErrorTime + errorMutex sync.Mutex +} + +func NewErrorFilter(leaseTTL time.Duration) *ErrorFilter { + return &ErrorFilter{ + errorMutex: sync.Mutex{}, + leaseTTL: leaseTTL, + } +} + +// ReportLeaseError reports that an operation that relies on the leader being up has failed +// If this is either the first report or the error is within the lease timeout duration from +// the time of the first report it will return false, indicating that this may be a transient error +// If it returns true then the error has persisted over the length of a lease, and is probably serious +// this will also return true if some operations are succeeding and some are failing, indicating a non-lease +// related transient error +func (c *ErrorFilter) ReportLeaseError() bool { + c.errorMutex.Lock() + defer c.errorMutex.Unlock() + errorTime, ok := c.firstErrorTime.Get() + if !ok { + c.firstErrorTime = optional.Some(time.Now()) + return false + } + // We have seen a success recorded, and a previous error + // within the lease timeout, this indicates transient errors are happening + if c.recordedSuccessTime.Ok() { + return true + } + if errorTime.Add(c.leaseTTL).After(time.Now()) { + // Within the lease window, it will probably be resolved when a new leader is elected + return false + } + return true +} + +// ReportOperationSuccess reports that an operation that relies on the leader being up has succeeded +// it is used to decide if an error is transient and will be fixed with a new leader, or if the error is persistent +func (c *ErrorFilter) ReportOperationSuccess() { + c.errorMutex.Lock() + defer c.errorMutex.Unlock() + errorTime, ok := c.firstErrorTime.Get() + if !ok { + // Normal operation, no errors + return + } + if errorTime.Add(c.leaseTTL).After(time.Now()) { + c.recordedSuccessTime = optional.Some(time.Now()) + } else { + // Outside the lease window, clear our state + c.recordedSuccessTime = optional.None[time.Time]() + c.firstErrorTime = optional.None[time.Time]() + } +} diff --git a/backend/controller/leader/leader_test.go b/backend/controller/leader/leader_test.go index 7d239b8a41..dd6f9ef295 100644 --- a/backend/controller/leader/leader_test.go +++ b/backend/controller/leader/leader_test.go @@ -125,6 +125,33 @@ func TestSingleLeader(t *testing.T) { ctxSlicesLock.Unlock() } +func TestLeaseErrorFilteringPersistentError(t *testing.T) { + filter := NewErrorFilter(time.Millisecond * 200) + assert.False(t, filter.ReportLeaseError(), "first error should be filtered") + assert.False(t, filter.ReportLeaseError(), "second error should be filtered") + assert.False(t, filter.ReportLeaseError(), "third error should be filtered") + time.Sleep(time.Millisecond * 201) + assert.True(t, filter.ReportLeaseError(), "third error should be reported") +} + +func TestLeaseErrorFilteringTransientError(t *testing.T) { + filter := NewErrorFilter(time.Millisecond * 200) + assert.False(t, filter.ReportLeaseError(), "first error should be filtered") + assert.False(t, filter.ReportLeaseError(), "second error should be filtered") + assert.False(t, filter.ReportLeaseError(), "third error should be filtered") + time.Sleep(time.Millisecond * 201) + filter.ReportOperationSuccess() + assert.False(t, filter.ReportLeaseError(), "first error again") +} + +func TestLeaseErrorTransientErrors(t *testing.T) { + filter := NewErrorFilter(time.Millisecond * 200) + assert.False(t, filter.ReportLeaseError(), "first error should be filtered") + assert.False(t, filter.ReportLeaseError(), "second error should be filtered") + filter.ReportOperationSuccess() + assert.True(t, filter.ReportLeaseError(), "success and failure within the TTL should be reported") +} + func leaderFromCoordinators(t *testing.T, coordinators []*Coordinator[string]) (leaderIdx int, leaderStr string) { t.Helper() diff --git a/common/configuration/asm.go b/common/configuration/asm.go index 4136409a2a..bcab586a00 100644 --- a/common/configuration/asm.go +++ b/common/configuration/asm.go @@ -52,18 +52,19 @@ func newASMForTesting(ctx context.Context, secretsClient *secretsmanager.Client, return override, nil } rpcClient := rpc.Dial(ftlv1connect.NewAdminServiceClient, url.String(), log.Error) - return newASMFollower(rpcClient, url.String()), nil + return newASMFollower(rpcClient, url.String(), time.Second*10), nil } + coordinator := leader.NewCoordinator[asmClient]( + ctx, + advertise, + leases.SystemKey("asm"), + leaser, + time.Second*10, + leaderFactory, + followerFactory, + ) return &ASM{ - coordinator: leader.NewCoordinator[asmClient]( - ctx, - advertise, - leases.SystemKey("asm"), - leaser, - time.Second*10, - leaderFactory, - followerFactory, - ), + coordinator: coordinator, } } diff --git a/common/configuration/asm_follower.go b/common/configuration/asm_follower.go index 60346483b7..de4710624a 100644 --- a/common/configuration/asm_follower.go +++ b/common/configuration/asm_follower.go @@ -2,6 +2,7 @@ package configuration import ( "context" + "errors" "fmt" "net/url" "time" @@ -9,26 +10,27 @@ import ( "connectrpc.com/connect" "github.com/puzpuzpuz/xsync/v3" + "github.com/TBD54566975/ftl/backend/controller/leader" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" + "github.com/TBD54566975/ftl/internal/log" ) const asmFollowerSyncInterval = time.Second * 10 // asmFollower uses AdminService to get/set secrets from the leader type asmFollower struct { - leaderName string - + errorFilter *leader.ErrorFilter + leaderName string // client requests/responses use unobfuscated values client ftlv1connect.AdminServiceClient } -var _ asmClient = &asmFollower{} - -func newASMFollower(rpcClient ftlv1connect.AdminServiceClient, leaderName string) *asmFollower { +func newASMFollower(rpcClient ftlv1connect.AdminServiceClient, leaderName string, leaseTTL time.Duration) *asmFollower { f := &asmFollower{ - leaderName: leaderName, - client: rpcClient, + errorFilter: leader.NewErrorFilter(leaseTTL), + leaderName: leaderName, + client: rpcClient, } return f } @@ -43,6 +45,7 @@ func (f *asmFollower) syncInterval() time.Duration { func (f *asmFollower) sync(ctx context.Context, values *xsync.MapOf[Ref, SyncedValue]) error { // values must store obfuscated values, but f.client gives unobfuscated values + logger := log.FromContext(ctx) obfuscator := Secrets{}.obfuscator() module := "" includeValues := true @@ -51,8 +54,17 @@ func (f *asmFollower) sync(ctx context.Context, values *xsync.MapOf[Ref, SyncedV IncludeValues: &includeValues, })) if err != nil { + if connectErr := new(connect.Error); errors.As(err, &connectErr) { + if connectErr.Code() == connect.CodeInternal || connectErr.Code() == connect.CodeUnavailable { + if !f.errorFilter.ReportLeaseError() { + logger.Warnf("error getting secrets list from leader, possible leader failover %s", err.Error()) + return nil + } + } + } return fmt.Errorf("error getting secrets list from leader: %w", err) } + f.errorFilter.ReportOperationSuccess() visited := map[Ref]bool{} for _, s := range resp.Msg.Secrets { ref, err := ParseRef(s.RefPath) diff --git a/common/configuration/asm_test.go b/common/configuration/asm_test.go index 4baf3ae46d..78086d9c3c 100644 --- a/common/configuration/asm_test.go +++ b/common/configuration/asm_test.go @@ -11,6 +11,7 @@ import ( "path" "sort" "testing" + "time" "github.com/TBD54566975/ftl/backend/controller/leases" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" @@ -177,7 +178,7 @@ func TestFollowerSync(t *testing.T) { // fakeRPCClient connects the follower to the leader fakeRPCClient := &fakeAdminClient{sm: leaderManager} - follower := newASMFollower(fakeRPCClient, "fake") + follower := newASMFollower(fakeRPCClient, "fake", time.Second) followerASM := newASMForTesting(ctx, externalClient, URL("http://localhost:1235"), leaser, optional.Some[asmClient](follower)) asmClient, err := followerASM.coordinator.Get() From 213c9e0ed5199fd4350e1f74fc962d92c27460c4 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 12 Aug 2024 13:25:47 +1000 Subject: [PATCH 12/35] fix: schema diff is reversed (#2323) fixes #2302 --- cmd/ftl/cmd_schema_diff.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/ftl/cmd_schema_diff.go b/cmd/ftl/cmd_schema_diff.go index 4572103f73..8576eb4356 100644 --- a/cmd/ftl/cmd_schema_diff.go +++ b/cmd/ftl/cmd_schema_diff.go @@ -33,7 +33,9 @@ func (d *schemaDiffCmd) Run(ctx context.Context, currentURL *url.URL, projConfig var other *schema.Schema var err error sameModulesOnly := false - if d.OtherEndpoint.String() == "" { + otherEndpoint := d.OtherEndpoint.String() + if otherEndpoint == "" { + otherEndpoint = "Local Changes" sameModulesOnly = true other, err = localSchema(ctx, projConfig) } else { @@ -61,8 +63,8 @@ func (d *schemaDiffCmd) Run(ctx context.Context, currentURL *url.URL, projConfig } } - edits := myers.ComputeEdits(span.URIFromPath(""), other.String(), current.String()) - diff := fmt.Sprint(gotextdiff.ToUnified(d.OtherEndpoint.String(), currentURL.String(), other.String(), edits)) + edits := myers.ComputeEdits(span.URIFromPath(""), current.String(), other.String()) + diff := fmt.Sprint(gotextdiff.ToUnified(currentURL.String(), otherEndpoint, current.String(), edits)) color := d.Color || isatty.IsTerminal(os.Stdout.Fd()) if color { From ef5094ede402fcfc13785baa74c9741a5278cc83 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Mon, 12 Aug 2024 13:47:05 +1000 Subject: [PATCH 13/35] ci: save downloaded NPM tarballs in the CI cache (#2324) --- .github/actions/build-cache/action.yml | 9 +++++++++ .github/workflows/writecache.yml | 11 ++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/actions/build-cache/action.yml b/.github/actions/build-cache/action.yml index 5d6ce349ab..dc51b9695f 100644 --- a/.github/actions/build-cache/action.yml +++ b/.github/actions/build-cache/action.yml @@ -31,5 +31,14 @@ runs: restore-keys: | ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} ${{ runner.os }}-maven- + - name: Restore NPM Cache + id: cache-npm + uses: actions/cache/restore@v4 + with: + path: .hermit/node/cache/_cacache + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} + ${{ runner.os }}-npm- diff --git a/.github/workflows/writecache.yml b/.github/workflows/writecache.yml index 3d1d4ade50..959a9c6e12 100644 --- a/.github/workflows/writecache.yml +++ b/.github/workflows/writecache.yml @@ -23,10 +23,13 @@ jobs: run: just build-all - name: Download Go Dependencies run: go mod download -x + - name: Download NPM Dependencies + run: find . -name package-lock.json -execdir npm ci \; - id: find-go-build-cache shell: bash run: echo "cache=$(go env GOCACHE)" >> "$GITHUB_OUTPUT" - - uses: actions/cache/save@v4 + - name: Save Go Module Cache + uses: actions/cache/save@v4 with: path: | ~/go/pkg/mod @@ -38,3 +41,9 @@ jobs: with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + - name: Save NPM Modules Cache + id: cache-npm + uses: actions/cache/save@v4 + with: + path: .hermit/node/cache/_cacache + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} From 709c49f9cd88c7d7b8dd10773a4ea9dd365fcf1e Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Mon, 12 Aug 2024 14:44:58 +1000 Subject: [PATCH 14/35] refactor: support explicit named Go migrations (#2325) Go migrations will need to be closures in order to inject dependencies, which breaks name reflection. --- backend/controller/sql/migrate/migrate.go | 79 ++++++++++++------- .../controller/sql/migrate/migrate_test.go | 74 +---------------- .../30280101000000_init.sql | 0 .../30280102000000_add_name_age.sql | 3 + .../migrationtest/30280103000000_split.go | 55 +++++++++++++ .../30280104000000_drop_column.sql | 4 + 6 files changed, 117 insertions(+), 98 deletions(-) rename backend/controller/sql/migrate/{testdata => migrationtest}/30280101000000_init.sql (100%) create mode 100644 backend/controller/sql/migrate/migrationtest/30280102000000_add_name_age.sql create mode 100644 backend/controller/sql/migrate/migrationtest/30280103000000_split.go create mode 100644 backend/controller/sql/migrate/migrationtest/30280104000000_drop_column.sql diff --git a/backend/controller/sql/migrate/migrate.go b/backend/controller/sql/migrate/migrate.go index 6fc73eada2..d2e44d95b8 100644 --- a/backend/controller/sql/migrate/migrate.go +++ b/backend/controller/sql/migrate/migrate.go @@ -11,9 +11,7 @@ import ( "fmt" "io/fs" "path/filepath" - "reflect" "regexp" - "runtime" "sort" "time" @@ -21,23 +19,45 @@ import ( "github.com/TBD54566975/ftl/internal/log" ) -var migrationFileNameRe = regexp.MustCompile(`^.*(\d{14})_(.*)\.sql$`) -var migrationFuncNameRe = regexp.MustCompile(`^.*\.Migrate(\d{14})(.*)$`) +var migrationFileNameRe = regexp.MustCompile(`^.*(\d{14})_(.*)(\.sql)?$`) -type Migration func(ctx context.Context, db *sql.Tx) error +type migrateOptions struct { + logLevel log.Level + migrations map[string]MigrationFunc +} + +// Option is a configuration option for Migrate. +type Option func(*migrateOptions) + +// Migration adds a named migration function to the migration set. +// +// "version" must be in the form "
". +func Migration(version, name string, migration MigrationFunc) Option { + return func(opts *migrateOptions) { + opts.migrations[version+"_"+name] = migration + } +} + +// LogLevel sets the loggging level of the migrator. +func LogLevel(level log.Level) Option { + return func(opts *migrateOptions) { + opts.logLevel = level + } +} + +type MigrationFunc func(ctx context.Context, db *sql.Tx) error type namedMigration struct { name string version string - migration Migration + migration MigrationFunc } func (m namedMigration) String() string { return m.name } -// Migrate applies all migrations in the provided fs.FS and migrationFuncs to the provided database. -// -// Migration functions must be named in the form "MigrationYYYYMMDDHHMMSS". -func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFuncs ...Migration) error { +// Migrate applies all migrations in the provided fs.FS and migration functions +// to the provided database. +func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, options ...Option) error { // Create schema_migrations table if it doesn't exist. // This table structure is compatible with dbmate. _, _ = db.ExecContext(ctx, `CREATE TABLE schema_migrations (version TEXT PRIMARY KEY)`) //nolint:errcheck @@ -47,14 +67,22 @@ func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFun return fmt.Errorf("failed to read migration files: %w", err) } - migrations := make([]namedMigration, 0, len(sqlFiles)+len(migrationFuncs)) + opts := migrateOptions{ + logLevel: log.Debug, + migrations: make(map[string]MigrationFunc), + } + for _, opt := range options { + opt(&opts) + } + + migrations := make([]namedMigration, 0, len(sqlFiles)+len(opts.migrations)) // Collect .sql files. for _, sqlFile := range sqlFiles { name := filepath.Base(sqlFile) groups := migrationFileNameRe.FindStringSubmatch(name) if groups == nil { - return fmt.Errorf("invalid migration file name %q, must be in the form _.sql", sqlFile) + return fmt.Errorf("invalid migration file name %q, must be in the form
_.sql", sqlFile) } version := groups[1] migrations = append(migrations, namedMigration{name, version, func(ctx context.Context, db *sql.Tx) error { @@ -65,8 +93,12 @@ func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFun return migrateSQLFile(ctx, db, sqlFile, sqlMigration) }}) } - for _, migration := range migrationFuncs { - name, version := migrationFuncVersion(migration) + for name, migration := range opts.migrations { + groups := migrationFileNameRe.FindStringSubmatch(name) + if groups == nil { + return fmt.Errorf("invalid migration name %q, must be in the form
_", name) + } + version := groups[1] migrations = append(migrations, namedMigration{name, version, migration}) } sort.Slice(migrations, func(i, j int) bool { @@ -77,7 +109,7 @@ func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFun if err != nil { return fmt.Errorf("migration %s: failed to begin transaction: %w", migration, err) } - err = applyMigration(ctx, tx, migration) + err = applyMigration(ctx, opts.logLevel, tx, migration) if err != nil { if txerr := tx.Rollback(); txerr != nil { return fmt.Errorf("migration %s: failed to rollback transaction: %w", migration, txerr) @@ -92,7 +124,7 @@ func Migrate(ctx context.Context, db *sql.DB, migrationFiles fs.FS, migrationFun return nil } -func applyMigration(ctx context.Context, tx *sql.Tx, migration namedMigration) error { +func applyMigration(ctx context.Context, level log.Level, tx *sql.Tx, migration namedMigration) error { start := time.Now() logger := log.FromContext(ctx).Scope("migrate") _, err := tx.ExecContext(ctx, "INSERT INTO schema_migrations (version) VALUES ($1)", migration.version) @@ -101,28 +133,19 @@ func applyMigration(ctx context.Context, tx *sql.Tx, migration namedMigration) e if txerr := tx.Rollback(); txerr != nil { return fmt.Errorf("failed to rollback transaction: %w", txerr) } - logger.Debugf("Skipping: %s", migration) + logger.Logf(level, "Skipping: %s", migration) return nil } else if err != nil { return fmt.Errorf("failed to insert migration: %w", err) } - logger.Debugf("Applying: %s", migration) + logger.Logf(level, "Applying: %s", migration) if err := migration.migration(ctx, tx); err != nil { return fmt.Errorf("migration failed: %w", err) } - logger.Debugf("Applied: %s in %s", migration, time.Since(start)) + logger.Logf(level, "Applied: %s in %s", migration, time.Since(start)) return nil } -func migrationFuncVersion(i any) (name string, version string) { - name = runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() - groups := migrationFuncNameRe.FindStringSubmatch(name) - if groups == nil { - panic(fmt.Sprintf("invalid migration name %q, must be in the form Migrate", name)) - } - return name, groups[1] -} - func migrateSQLFile(ctx context.Context, db *sql.Tx, name string, sqlMigration []byte) error { _, err := db.ExecContext(ctx, string(sqlMigration)) if err != nil { diff --git a/backend/controller/sql/migrate/migrate_test.go b/backend/controller/sql/migrate/migrate_test.go index 07eadd8f9a..17cc026c7d 100644 --- a/backend/controller/sql/migrate/migrate_test.go +++ b/backend/controller/sql/migrate/migrate_test.go @@ -2,16 +2,13 @@ package migrate import ( "context" - "database/sql" "embed" - "fmt" "io/fs" - "strconv" - "strings" "testing" "github.com/alecthomas/assert/v2" + "github.com/TBD54566975/ftl/backend/controller/sql/migrate/migrationtest" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" "github.com/TBD54566975/ftl/internal/log" ) @@ -20,10 +17,10 @@ func TestMigrate(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) db := sqltest.OpenForTesting(ctx, t) - mfs, err := fs.Sub(migrations, "testdata") + mfs, err := fs.Sub(migrations, "migrationtest") assert.NoError(t, err) - err = Migrate(ctx, db, mfs, Migrate30280103221530SplitNameAge) + err = Migrate(ctx, db, mfs, Migration("30280103000000", "split_name_age", migrationtest.MigrateSplitNameAge)) assert.NoError(t, err) rows, err := db.QueryContext(ctx, "SELECT name, age FROM test") @@ -45,68 +42,5 @@ func TestMigrate(t *testing.T) { assert.Equal(t, expected, actual) } -//go:embed testdata +//go:embed migrationtest var migrations embed.FS - -func Migrate30280103221530SplitNameAge(ctx context.Context, tx *sql.Tx) error { - _, err := tx.ExecContext(ctx, ` - ALTER TABLE test - ADD COLUMN name TEXT, - ADD COLUMN age INT - `) - if err != nil { - return fmt.Errorf("failed to add columns: %w", err) - } - rows, err := tx.QueryContext(ctx, "SELECT id, name_and_age FROM test") - if err != nil { - return fmt.Errorf("failed to query test: %w", err) - } - defer rows.Close() - type userUpdate struct { - name string - age int64 - } - updates := map[int]userUpdate{} - for rows.Next() { - var id int - var name string - var age int64 - err = rows.Scan(&id, &name) - if err != nil { - return fmt.Errorf("failed to scan user: %w", err) - } - nameAge := strings.Fields(name) - name = nameAge[0] - switch len(nameAge) { - case 1: - case 2: - age, err = strconv.ParseInt(nameAge[1], 10, 64) - if err != nil { - return fmt.Errorf("failed to parse age: %w", err) - } - default: - return fmt.Errorf("invalid name %q", name) - } - // We can't update the table while iterating over it, so we store the updates in a map. - updates[id] = userUpdate{name, age} - } - if err := rows.Close(); err != nil { - return fmt.Errorf("failed to close rows: %w", err) - } - for id, update := range updates { - _, err = tx.ExecContext(ctx, "UPDATE test SET name = $1, age = $2 WHERE id = $3", update.name, update.age, id) - if err != nil { - return fmt.Errorf("failed to update user %d: %w", id, err) - } - } - _, err = tx.ExecContext(ctx, ` - ALTER TABLE test - DROP COLUMN name_and_age, - ALTER COLUMN name SET NOT NULL, - ALTER COLUMN age SET NOT NULL - `) - if err != nil { - return fmt.Errorf("failed to drop column: %w", err) - } - return nil -} diff --git a/backend/controller/sql/migrate/testdata/30280101000000_init.sql b/backend/controller/sql/migrate/migrationtest/30280101000000_init.sql similarity index 100% rename from backend/controller/sql/migrate/testdata/30280101000000_init.sql rename to backend/controller/sql/migrate/migrationtest/30280101000000_init.sql diff --git a/backend/controller/sql/migrate/migrationtest/30280102000000_add_name_age.sql b/backend/controller/sql/migrate/migrationtest/30280102000000_add_name_age.sql new file mode 100644 index 0000000000..c80dd07b9f --- /dev/null +++ b/backend/controller/sql/migrate/migrationtest/30280102000000_add_name_age.sql @@ -0,0 +1,3 @@ + ALTER TABLE test + ADD COLUMN name TEXT, + ADD COLUMN age INT; \ No newline at end of file diff --git a/backend/controller/sql/migrate/migrationtest/30280103000000_split.go b/backend/controller/sql/migrate/migrationtest/30280103000000_split.go new file mode 100644 index 0000000000..7a21b05001 --- /dev/null +++ b/backend/controller/sql/migrate/migrationtest/30280103000000_split.go @@ -0,0 +1,55 @@ +package migrationtest + +import ( + "context" + "database/sql" + "fmt" + "strconv" + "strings" +) + +func MigrateSplitNameAge(ctx context.Context, tx *sql.Tx) error { + rows, err := tx.QueryContext(ctx, "SELECT id, name_and_age FROM test") + if err != nil { + return fmt.Errorf("failed to query test: %w", err) + } + defer rows.Close() + type userUpdate struct { + name string + age int64 + } + updates := map[int]userUpdate{} + for rows.Next() { + var id int + var name string + var age int64 + err = rows.Scan(&id, &name) + if err != nil { + return fmt.Errorf("failed to scan user: %w", err) + } + nameAge := strings.Fields(name) + name = nameAge[0] + switch len(nameAge) { + case 1: + case 2: + age, err = strconv.ParseInt(nameAge[1], 10, 64) + if err != nil { + return fmt.Errorf("failed to parse age: %w", err) + } + default: + return fmt.Errorf("invalid name %q", name) + } + // We can't update the table while iterating over it, so we store the updates in a map. + updates[id] = userUpdate{name, age} + } + if err := rows.Close(); err != nil { + return fmt.Errorf("failed to close rows: %w", err) + } + for id, update := range updates { + _, err = tx.ExecContext(ctx, "UPDATE test SET name = $1, age = $2 WHERE id = $3", update.name, update.age, id) + if err != nil { + return fmt.Errorf("failed to update user %d: %w", id, err) + } + } + return nil +} diff --git a/backend/controller/sql/migrate/migrationtest/30280104000000_drop_column.sql b/backend/controller/sql/migrate/migrationtest/30280104000000_drop_column.sql new file mode 100644 index 0000000000..93221ae0bd --- /dev/null +++ b/backend/controller/sql/migrate/migrationtest/30280104000000_drop_column.sql @@ -0,0 +1,4 @@ +ALTER TABLE test + DROP COLUMN name_and_age, + ALTER COLUMN name SET NOT NULL, + ALTER COLUMN age SET NOT NULL \ No newline at end of file From 5b042bd52415d4e496daf0894130e55a837cfb18 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:24:46 +1000 Subject: [PATCH 15/35] chore(deps): update dependency postcss-nesting to v13 (#2316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [postcss-nesting](https://togithub.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting#readme) ([source](https://togithub.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-nesting)) | [`12.1.5` -> `13.0.0`](https://renovatebot.com/diffs/npm/postcss-nesting/12.1.5/13.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/postcss-nesting/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/postcss-nesting/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/postcss-nesting/12.1.5/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss-nesting/12.1.5/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
csstools/postcss-plugins (postcss-nesting) ### [`v13.0.0`](https://togithub.com/csstools/postcss-plugins/blob/HEAD/plugins/postcss-nesting/CHANGELOG.md#1300) [Compare Source](https://togithub.com/csstools/postcss-plugins/compare/f8703cf198bce71dbced271585eee2fe502b8ff6...5738117bb517923eeef00087ff86c1cbbd60cc1f) *August 3, 2024* - Make edition `2024-02` the default (major). - Updated: Support for Node v18+ (major). - Updated [`@csstools/selector-resolve-nested`](https://togithub.com/csstools/postcss-plugins/tree/main/packages/selector-resolve-nested) to [`2.0.0`](https://togithub.com/csstools/postcss-plugins/tree/main/packages/selector-resolve-nested/CHANGELOG.md#200) (major) - Updated [`@csstools/selector-specificity`](https://togithub.com/csstools/postcss-plugins/tree/main/packages/selector-specificity) to [`4.0.0`](https://togithub.com/csstools/postcss-plugins/tree/main/packages/selector-specificity/CHANGELOG.md#400) (major)
--- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/TBD54566975/ftl). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 37 ++++++++++++++++++++----------------- frontend/package.json | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ed6e3ffafd..9c3ba37e65 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -59,7 +59,7 @@ "fast-glob": "3.3.2", "lint-staged": "15.2.8", "postcss": "8.4.41", - "postcss-nesting": "12.1.5", + "postcss-nesting": "13.0.0", "storybook": "^8.2.7", "storybook-dark-mode": "^4.0.2", "typed-css-modules": "0.9.1", @@ -2335,9 +2335,9 @@ } }, "node_modules/@csstools/selector-resolve-nested": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz", - "integrity": "sha512-uWvSaeRcHyeNenKg8tp17EVDRkpflmdyvbE0DHo6D/GdBb6PDnCYYU6gRpXhtICMGMcahQmj2zGxwFM/WC8hCg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-2.0.0.tgz", + "integrity": "sha512-oklSrRvOxNeeOW1yARd4WNCs/D09cQjunGZUgSq6vM8GpzFswN+8rBZyJA29YFZhOTQ6GFzxgLDNtVbt9wPZMA==", "dev": true, "funding": [ { @@ -2349,17 +2349,18 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "postcss-selector-parser": "^6.1.0" } }, "node_modules/@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz", + "integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==", "dev": true, "funding": [ { @@ -2371,11 +2372,12 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "postcss-selector-parser": "^6.1.0" } }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { @@ -13971,9 +13973,9 @@ } }, "node_modules/postcss-nesting": { - "version": "12.1.5", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.1.5.tgz", - "integrity": "sha512-N1NgI1PDCiAGWPTYrwqm8wpjv0bgDmkYHH72pNsqTCv9CObxjxftdYu6AKtGN+pnJa7FQjMm3v4sp8QJbFsYdQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.0.tgz", + "integrity": "sha512-TCGQOizyqvEkdeTPM+t6NYwJ3EJszYE/8t8ILxw/YoeUvz2rz7aM8XTAmBWh9/DJjfaaabL88fWrsVHSPF2zgA==", "dev": true, "funding": [ { @@ -13985,13 +13987,14 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "dependencies": { - "@csstools/selector-resolve-nested": "^1.1.0", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/selector-resolve-nested": "^2.0.0", + "@csstools/selector-specificity": "^4.0.0", "postcss-selector-parser": "^6.1.0" }, "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { "postcss": "^8.4" diff --git a/frontend/package.json b/frontend/package.json index 801ae5eb90..12b3b38536 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -74,7 +74,7 @@ "fast-glob": "3.3.2", "lint-staged": "15.2.8", "postcss": "8.4.41", - "postcss-nesting": "12.1.5", + "postcss-nesting": "13.0.0", "storybook": "^8.2.7", "storybook-dark-mode": "^4.0.2", "typed-css-modules": "0.9.1", From 001a3d2544cc9b6b20e2ebfff204e070459603ac Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 12 Aug 2024 17:40:38 +1000 Subject: [PATCH 16/35] fix: ftl new fails (#2326) The directory was being prefixed to the path twice. fixes #2297 --- cmd/ftl/cmd_new.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/ftl/cmd_new.go b/cmd/ftl/cmd_new.go index 7f5c2fc58c..7a93c15df6 100644 --- a/cmd/ftl/cmd_new.go +++ b/cmd/ftl/cmd_new.go @@ -79,7 +79,7 @@ func (i newGoCmd) Run(ctx context.Context) error { return err } } - if err := maybeGitAdd(ctx, i.Dir, filepath.Join(path, "*")); err != nil { + if err := maybeGitAdd(ctx, i.Dir, filepath.Join(i.Name, "*")); err != nil { return err } } From a930215d121c9503d1dc49b5cdb1c4b556d1e7e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:41:52 -0700 Subject: [PATCH 17/35] chore(deps): update typescript-eslint monorepo to v8 (major) (#2322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)) | [`^7.4.0` -> `^8.0.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)) | [`^7.5.0` -> `^8.0.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2feslint-plugin/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`^7.4.0` -> `^8.0.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/7.18.0/8.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://togithub.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`^7.5.0` -> `^8.0.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/7.18.0/8.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/7.18.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin) ### [`v8.0.1`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#801-2024-08-05) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v8.0.0...v8.0.1) ##### 🩹 Fixes - **eslint-plugin:** \[no-unused-vars] ignore imports used only as types ##### ❤️ Thank You - Jake Bailey You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. ### [`v8.0.0`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#800-2024-07-31) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v7.18.0...v8.0.0) ##### 🚀 Features - stricter parent types for the AST - **typescript-estree:** split TSMappedType typeParameter into constraint and key - **eslint-plugin:** remove formatting/layout rules - **eslint-plugin:** \[prefer-nullish-coalescing] change ignoreConditionalTests default to true - **eslint-plugin:** deprecate no-loss-of-precision extension rule - **eslint-plugin:** \[no-unused-vars] align catch behavior to ESLint 9 - **typescript-estree:** rename automaticSingleRunInference to disallowAutomaticSingleRunInference - **utils:** allow specifying additional rule meta.docs in RuleCreator - **eslint-plugin:** split no-empty-object-type out from ban-types and no-empty-interfaces - **rule-tester:** support multipass fixes - **typescript-estree:** stabilize EXPERIMENTAL_useProjectService as projectService - **eslint-plugin:** remove deprecated no-throw-literal rule - **eslint-plugin:** apply initial config changes for v8 - **eslint-plugin:** remove no-useless-template-literals - **eslint-plugin:** \[no-floating-promises] add 'allowForKnownSafeCalls' option - **eslint-plugin:** replace ban-types with no-restricted-types, no-unsafe-function-type, no-wrapper-object-types - **eslint-plugin:** \[no-unused-vars] add `reportUnusedIgnorePattern` option - **eslint-plugin:** \[no-unused-vars] support `ignoreClassWithStaticInitBlock` - **eslint-plugin:** \[no-unused-vars] handle comma operator for assignments, treat for-of the same as for-in - **eslint-plugin:** \[no-unused-vars] report if var used only in typeof - **eslint-plugin:** \[no-floating-promises] disable checkThenables by default for v8 - **rule-tester:** switched to flat config - **eslint-plugin:** \[no-unnecessary-type-parameters] promote to strict ##### 🩹 Fixes - correct eslint-plugin's peerDependency on parser@8 - disable `projectService` in `disabled-type-checked` shared config - **typescript-estree:** add TSEnumBody node for TSEnumDeclaration body - **eslint-plugin:** include alpha pre-releases in parser peer dependency - **eslint-plugin:** correct rules.d.ts types to not rely on non-existent imports - **eslint-plugin:** remove duplicate import `RuleModuleWithMetaDocs` - **type-utils:** also check declared modules for package names in TypeOrValueSpecifier - **eslint-plugin:** \[no-unnecessary-template-expression] do not render escaped strings in autofixes - **eslint-plugin:** \[no-unused-vars] incorporate upstream changes around caught errors report messages - **eslint-plugin:** \[no-misused-promises] perf: avoid getting types of variables/functions if the annotated type is obviously not a function - **rule-tester:** provide Linter a cwd in its constructor ##### ❤️ Thank You - Abraham Guo - Alfred Ringstad - auvred - Brad Zacher - Christopher Aubut - Collin Bachman - James Henry - Josh Goldberg - Josh Goldberg ✨ - Kirk Waiblinger - StyleShit - Victor Lin - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.18.0 (2024-07-29) ##### 🩹 Fixes - **eslint-plugin:** \[no-unnecessary-type-assertion] prevent runtime error when asserting a variable declared in default TS lib - **eslint-plugin:** \[unbound-method] report on destructuring in function parameters - **eslint-plugin:** \[no-duplicate-type-constituents] shouldn't report on error types - **eslint-plugin:** \[strict-boolean-expressions] support branded booleans ##### ❤️ Thank You - auvred - Oliver Salzburg - Vinccool96 - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.17.0 (2024-07-22) ##### 🚀 Features - **eslint-plugin:** backport no-unsafe-function type, no-wrapper-object-types from v8 to v7 - **eslint-plugin:** \[return-await] add option to report in error-handling scenarios only, and deprecate "never" ##### 🩹 Fixes - **eslint-plugin:** \[no-floating-promises] check top-level type assertions (and more) - **eslint-plugin:** \[strict-boolean-expressions] consider assertion function argument a boolean context - **eslint-plugin:** \[no-unnecessary-condition] false positive on optional private field ##### ❤️ Thank You - Armano - Josh Goldberg ✨ - Kirk Waiblinger - StyleShit You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.16.1 (2024-07-15) ##### 🩹 Fixes - **eslint-plugin:** \[no-unnecessary-type-parameters] descend into all parts of mapped types in no-unnecessary-type-parameters ##### ❤️ Thank You - Dan Vanderkam You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.16.0 (2024-07-08) ##### 🚀 Features - **rule-tester:** stricter rule test validations - **eslint-plugin:** \[no-unnecessary-parameter-property-assignment] add new rule - **eslint-plugin:** add support for nested namespaces to unsafe-member-access - **eslint-plugin:** \[no-floating-promises] add checkThenables option ##### 🩹 Fixes - **deps:** update dependency [@​eslint-community/regexpp](https://togithub.com/eslint-community/regexpp) to v4.11.0 - **eslint-plugin:** \[no-floating-promises] add `suggestions` to tests from [#​9263](https://togithub.com/typescript-eslint/typescript-eslint/issues/9263) `checkThenables` - **website:** react key error on internal pages of website - **eslint-plugin:** \[restrict-template-expressions] don't report tuples if `allowArray` option is enabled ##### ❤️ Thank You - Abraham Guo - auvred - Josh Goldberg ✨ - Juan Sanchez - Vinccool96 - YeonJuan - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.15.0 (2024-07-01) ##### 🚀 Features - **eslint-plugin:** \[array-type] detect `Readonly` case - **eslint-plugin:** back-port new rules around empty object types from v8 ##### 🩹 Fixes - disable `EXPERIMENTAL_useProjectService` in `disabled-type-checked` shared config - **eslint-plugin:** \[no-unsafe-return] differentiate a types-error any from a true any - **eslint-plugin:** \[no-unsafe-call] differentiate a types-error any from a true any ##### ❤️ Thank You - auvred - Kim Sang Du - rgehbt - Vinccool96 You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.14.1 (2024-06-24) ##### 🩹 Fixes - **eslint-plugin:** \[prefer-nullish-coalescing] treat enums and literals as their underlying primitive types - **eslint-plugin:** \[prefer-nullish-coalescing] ensure ternary fix does not remove parens ##### ❤️ Thank You - Jake Bailey You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.14.0 (2024-06-24) ##### 🚀 Features - support TypeScript 5.5 ##### 🩹 Fixes - **eslint-plugin:** \[no-extraneous-class] handle abstract members - **eslint-plugin:** \[prefer-nullish-coalescing] handle intersected primitive types - **eslint-plugin:** \[no-invalid-this] support AccessorProperty ##### ❤️ Thank You - Brad Zacher - cm-ayf - Jake Bailey - James Zhan - Joshua Chen - yoshi2no You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.13.1 (2024-06-17) ##### 🩹 Fixes - **eslint-plugin:** \[prefer-readonly] refine report locations - **eslint-plugin:** \[return-await] support explicit resource management - **eslint-plugin:** \[no-unsafe-member-access] differentiate a types-error any from a true any ##### ❤️ Thank You - Kirk Waiblinger - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.13.0 (2024-06-10) ##### 🚀 Features - **typescript-estree:** require `import = require()` argument to be a string literal - **typescript-estree:** forbid `.body`, `.async`, `.generator` on `declare function` - **eslint-plugin:** \[no-dynamic-delete] allow all string literals as index ##### 🩹 Fixes - **ast-spec:** function-call-like callee should be Expression not LeftHandSideExpression - **scope-manager:** handle index signature in class - **eslint-plugin:** \[init-declarations] refine report locations - **eslint-plugin:** \[no-base-to-string] make error message more nuanced - **eslint-plugin:** \[no-unsafe-assignment] be more specific about error types - **eslint-plugin:** \[no-magic-numbers] fix implementation of the `ignore` option ##### ❤️ Thank You - Fotis Papadogeorgopoulos - Joshua Chen - Kirk Waiblinger - Tobiloba Adedeji - Vinccool96 - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.12.0 (2024-06-03) ##### 🚀 Features - **eslint-plugin:** \[no-useless-template-literals] rename to `no-useless-template-expression` (deprecate `no-useless-template-literals`) - **rule-tester:** check for parsing errors in suggestion fixes - **rule-tester:** port `checkDuplicateTestCases` from ESLint - **eslint-plugin:** \[no-floating-promises] add option 'allowForKnownSafePromises' ##### 🩹 Fixes - no-useless-template-expression -> no-unnecessary-template-expression - **eslint-plugin:** \[no-unnecessary-type-assertion] combine template literal check with `const` variable check - **eslint-plugin:** \[dot-notation] fix false positive when accessing private/protected property with optional chaining - **eslint-plugin:** \[explicit-member-accessibility] refine report locations - **eslint-plugin:** \[no-unnecessary-type-assertion] declares are always defined, so always check `declare`s - **eslint-plugin:** \[prefer-literal-enum-member] allow using member it self on allowBitwiseExpressions - **eslint-plugin:** \[return-await] clean up in-try-catch detection and make autofixes safe - **eslint-plugin:** \[member-ordering] also TSMethodSignature can be get/set ##### ❤️ Thank You - Abraham Guo - Han Yeong-woo - Joshua Chen - Kim Sang Du - Kirk Waiblinger - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.11.0 (2024-05-27) ##### 🚀 Features - **eslint-plugin:** deprecate prefer-ts-expect-error in favor of ban-ts-comment ##### 🩹 Fixes - **eslint-plugin:** \[consistent-type-assertions] prevent syntax errors on arrow functions ##### ❤️ Thank You - Abraham Guo - auvred - Dom Armstrong - Kirk Waiblinger You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.10.0 (2024-05-20) ##### 🚀 Features - **eslint-plugin:** \[sort-type-constituents] support case sensitive sorting ##### 🩹 Fixes - **eslint-plugin:** \[prefer-regexp-exec] fix heuristic to check whether regex may contain global flag ##### ❤️ Thank You - auvred - Emanuel Hoogeveen - jsfm01 - Kirk Waiblinger You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.9.0 (2024-05-13) ##### 🩹 Fixes - **eslint-plugin:** \[explicit-function-return-types] fix false positive on default parameters ##### ❤️ Thank You - Kirk Waiblinger - Sheetal Nandi - Vinccool96 You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.8.0 (2024-04-29) ##### 🩹 Fixes - **eslint-plugin:** \[no-unsafe-argument] handle tagged templates - **eslint-plugin:** \[prefer-optional-chain] suggests optional chaining during strict null equality check - **eslint-plugin:** \[consistent-type-assertions] handle tagged templates - **eslint-plugin:** \[no-unsafe-return] handle union types - **eslint-plugin:** \[no-unused-vars] clear error report range ##### ❤️ Thank You - auvred - Josh Goldberg ✨ - jsfm01 - Kim Sang Du - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.7.1 (2024-04-22) ##### 🩹 Fixes - **eslint-plugin:** \[no-unsafe-assignment] handle shorthand property assignment - **eslint-plugin:** \[explicit-function-return-type] fix checking wrong ancestor's return type - **eslint-plugin:** \[prefer-optional-chain] only look at left operand for `requireNullish` - **eslint-plugin:** \[no-for-in-array] refine report location - **eslint-plugin:** \[no-unnecessary-type-assertion] allow non-null assertion for void type ##### ❤️ Thank You - Abraham Guo - Kirk Waiblinger - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.7.0 (2024-04-15) ##### 🚀 Features - **eslint-plugin:** replace `no-new-symbol` with `no-new-native-nonconstructor` ##### ❤️ Thank You - Dave - Josh Goldberg ✨ You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.6.0 (2024-04-08) ##### 🚀 Features - bump npm dependency ranges ##### ❤️ Thank You - Abraham Guo - auvred - Brad Zacher You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.5.0 (2024-04-01) ##### 🩹 Fixes - **eslint-plugin:** \[no-floating-promises] handle TaggedTemplateExpression - **eslint-plugin:** \[no-unnecessary-type-assertion] handle exactOptionalPropertyTypes compiler option ##### ❤️ Thank You - Brad Zacher - Kim Sang Du - Mark de Dios - Naru - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.4.0 (2024-03-25) ##### 🚀 Features - **eslint-plugin:** \[consistent-type-imports] ignore files with decorators, experimentalDecorators, and emitDecoratorMetadata - **eslint-plugin:** \[no-unnecessary-type-arguments] handle tagged templates - **eslint-plugin:** deprecate no-throw-literal and add a renamed only-throw-error ##### 🩹 Fixes - **eslint-plugin:** \[prefer-optional-chain] address multipart nullish checks false positive - **eslint-plugin:** \[prefer-optional-chain] properly disambiguate between `boolean` and `false` - **eslint-plugin:** \[no-unnecessary-type-assertion] avoid remove const casting on template literals with expressions inside ##### ❤️ Thank You - Abraham Guo - Brad Zacher - Josh Goldberg ✨ - Kim Sang Du - Kirk Waiblinger - Marco Pasqualetti - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.3.1 (2024-03-18) ##### 🩹 Fixes - **eslint-plugin:** \[no-floating-promises] revert disable of ignoreVoid in strict config ##### ❤️ Thank You - Josh Goldberg ✨ You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.3.0 (2024-03-18) ##### 🚀 Features - **eslint-plugin:** \[restrict-template-expressions] add `allowArray` option - **eslint-plugin:** add meta.docs.recommended setting for strict config options - **eslint-plugin:** add rule `use-unknown-in-catch-callback-variables` - **eslint-plugin:** \[prefer-reduce-type-parameter] supports tuple, union, intersection ##### 🩹 Fixes - correct `engines.node` constraints in `package.json` - **eslint-plugin:** \[unbound-method] check method definition in object literal using longhand form - **eslint-plugin:** \[consistent-type-imports] handle imports without specifiers - **eslint-plugin:** \[no-redundant-type-constituents] incorrectly marks & string as redundant - **eslint-plugin:** \[no-unnecessary-qualifier] handle merge namespace with enum - **eslint-plugin:** \[no-unused-expressions] false negatives when using assertions - **eslint-plugin:** \[ban-ts-comment] more accurate handling of multiline comments - **eslint-plugin:** \[explicit-function-return-type, explicit-module-boundary-types] improved checking for allowHigherOrderFunctions option - **eslint-plugin:** \[class-literal-property-style] ignore property assigned in constructor - **eslint-plugin:** \[no-unnecessary-type-assertion] fix false negative for const variable declarations ##### ❤️ Thank You - Abraham Guo - Alexu - Arka Pratim Chaudhuri - auvred - Derrick Isaacson - fnx - Josh Goldberg ✨ - Kirk Waiblinger - Marta Cardoso - Michaël De Boey - Tristan Rasmussen - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.2.0 (2024-03-11) ##### 🚀 Features - support TS 5.4 - **eslint-plugin:** \[prefer-string-starts-ends-with] add allowSingleElementEquality option ##### 🩹 Fixes - **eslint-plugin:** expose \*-type-checked-only configs for extension - **eslint-plugin:** \[member-ordering] report alphabetical sorting for all groups instead of just the first failing group - **eslint-plugin:** \[no-var-requires, no-require-imports] support template literal - **eslint-plugin:** \[no-useless-template-literals] detect TemplateLiteral - **eslint-plugin:** \[no-unnecessary-condition] handle union array and tuple type - **eslint-plugin:** \[prefer-find] support ternary branches in prefer-find ##### ❤️ Thank You - Arka Pratim Chaudhuri - auvred - Chris Plummer - Fotis Papadogeorgopoulos - Josh Goldberg ✨ - Kirk Waiblinger - Wayne Zhang - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.1.1 (2024-03-04) This was a version bump only for eslint-plugin to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.1.0 (2024-02-26) ##### 🚀 Features - **eslint-plugin:** add \*-type-checked-only configs - **eslint-plugin:** \[naming-convention] support the auto-accessor syntax - **eslint-plugin:** \[consistent-return] add new rule ##### 🩹 Fixes - **eslint-plugin:** \[prefer-optional-chan] allow typeof for avoiding reference error - **eslint-plugin:** \[no-misused-promises] improve check union types - **eslint-plugin:** \[no-use-before-define] fix false positive type reference in as, satisfies ##### ❤️ Thank You - Arka Pratim Chaudhuri - Josh Goldberg ✨ - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.0.2 (2024-02-19) ##### 🩹 Fixes - fix tsconfig-less check errors, fix `@types/eslint` incompatibilities, add tests ##### ❤️ Thank You - Brad Zacher - Gareth Jones You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.0.1 (2024-02-12) ##### 🩹 Fixes - **eslint-plugin:** update peer dep for parser ##### ❤️ Thank You - Tim Dorr You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.0.1`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#801-2024-08-05) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v8.0.0...v8.0.1) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. ### [`v8.0.0`](https://togithub.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#800-2024-07-31) [Compare Source](https://togithub.com/typescript-eslint/typescript-eslint/compare/v7.18.0...v8.0.0) ##### 🚀 Features - **parser:** always enable comment, loc, range, tokens - **typescript-estree:** stabilize EXPERIMENTAL_useProjectService as projectService ##### ❤️ Thank You - Abraham Guo - Alfred Ringstad - auvred - Brad Zacher - Christopher Aubut - Collin Bachman - James Henry - Josh Goldberg - Josh Goldberg ✨ - Kirk Waiblinger - StyleShit - Victor Lin - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.18.0 (2024-07-29) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.17.0 (2024-07-22) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.16.1 (2024-07-15) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.16.0 (2024-07-08) ##### 🩹 Fixes - **deps:** update dependency [@​eslint-community/regexpp](https://togithub.com/eslint-community/regexpp) to v4.11.0 - **website:** react key error on internal pages of website ##### ❤️ Thank You - Abraham Guo - auvred - Josh Goldberg ✨ - Juan Sanchez - Vinccool96 - YeonJuan - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.15.0 (2024-07-01) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.14.1 (2024-06-24) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.14.0 (2024-06-24) ##### 🚀 Features - support TypeScript 5.5 ##### ❤️ Thank You - Brad Zacher - cm-ayf - Jake Bailey - James Zhan - Joshua Chen - yoshi2no You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.13.1 (2024-06-17) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.13.0 (2024-06-10) ##### 🚀 Features - **parser, typescript-estree:** export withoutProjectParserOptions utility ##### ❤️ Thank You - Fotis Papadogeorgopoulos - Joshua Chen - Kirk Waiblinger - Tobiloba Adedeji - Vinccool96 - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.12.0 (2024-06-03) ##### 🩹 Fixes - **types:** correct typing ParserOptions ##### ❤️ Thank You - Abraham Guo - Han Yeong-woo - Joshua Chen - Kim Sang Du - Kirk Waiblinger - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.11.0 (2024-05-27) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.10.0 (2024-05-20) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.9.0 (2024-05-13) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.8.0 (2024-04-29) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.7.1 (2024-04-22) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.7.0 (2024-04-15) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.6.0 (2024-04-08) ##### 🚀 Features - bump npm dependency ranges ##### ❤️ Thank You - Abraham Guo - auvred - Brad Zacher You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.5.0 (2024-04-01) ##### 🩹 Fixes - **parser:** disallow `errorOnTypeScriptSyntacticAndSemanticIssues` ##### ❤️ Thank You - Brad Zacher - Kim Sang Du - Mark de Dios - Naru - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.4.0 (2024-03-25) ##### 🚀 Features - **eslint-plugin:** \[consistent-type-imports] ignore files with decorators, experimentalDecorators, and emitDecoratorMetadata ##### ❤️ Thank You - Abraham Guo - Brad Zacher - Josh Goldberg ✨ - Kim Sang Du - Kirk Waiblinger - Marco Pasqualetti - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.3.1 (2024-03-18) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.3.0 (2024-03-18) ##### 🩹 Fixes - correct `engines.node` constraints in `package.json` ##### ❤️ Thank You - Abraham Guo - Alexu - Arka Pratim Chaudhuri - auvred - Derrick Isaacson - fnx - Josh Goldberg ✨ - Kirk Waiblinger - Marta Cardoso - Michaël De Boey - Tristan Rasmussen - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.2.0 (2024-03-11) ##### 🚀 Features - support TS 5.4 ##### ❤️ Thank You - Arka Pratim Chaudhuri - auvred - Chris Plummer - Fotis Papadogeorgopoulos - Josh Goldberg ✨ - Kirk Waiblinger - Wayne Zhang - YeonJuan You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.1.1 (2024-03-04) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.1.0 (2024-02-26) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.0.2 (2024-02-19) ##### 🩹 Fixes - fix tsconfig-less check errors, fix `@types/eslint` incompatibilities, add tests ##### ❤️ Thank You - Brad Zacher - Gareth Jones You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. #### 7.0.1 (2024-02-12) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/TBD54566975/ftl). --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Wes --- extensions/vscode/package-lock.json | 115 +++++++++---------- extensions/vscode/package.json | 4 +- frontend/package-lock.json | 115 +++++++++---------- frontend/package.json | 4 +- frontend/src/components/CodeEditor.tsx | 4 +- frontend/src/features/graph/create-layout.ts | 2 - 6 files changed, 119 insertions(+), 125 deletions(-) diff --git a/extensions/vscode/package-lock.json b/extensions/vscode/package-lock.json index 97667b1f4a..9ae760b513 100644 --- a/extensions/vscode/package-lock.json +++ b/extensions/vscode/package-lock.json @@ -17,8 +17,8 @@ "@types/node": "20.x", "@types/semver": "^7.5.8", "@types/vscode": "^1.87.0", - "@typescript-eslint/eslint-plugin": "^7.5.0", - "@typescript-eslint/parser": "^7.5.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.29.0", @@ -622,32 +622,32 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", + "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/type-utils": "8.0.1", + "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -656,27 +656,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", + "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -685,17 +685,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", + "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -703,27 +703,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", + "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/utils": "8.0.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -731,13 +728,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", + "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -745,14 +742,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", + "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -761,7 +758,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -774,40 +771,40 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", + "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", + "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 92bf2e0df1..79f4e3882b 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -88,8 +88,8 @@ "@types/node": "20.x", "@types/semver": "^7.5.8", "@types/vscode": "^1.87.0", - "@typescript-eslint/eslint-plugin": "^7.5.0", - "@typescript-eslint/parser": "^7.5.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.3.9", "eslint": "^8.57.0", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9c3ba37e65..029edcf7d0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -49,8 +49,8 @@ "@storybook/test": "^8.2.7", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "buffer": "^6.0.3", "chokidar": "3.6.0", "eslint": "^8.57.0", @@ -6909,32 +6909,32 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", + "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/type-utils": "8.0.1", + "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -6943,27 +6943,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", + "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -6972,17 +6972,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", + "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -6990,27 +6990,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", + "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/utils": "8.0.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -7018,13 +7015,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", + "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -7032,14 +7029,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", + "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7048,7 +7045,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -7061,40 +7058,40 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", + "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", + "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", diff --git a/frontend/package.json b/frontend/package.json index 12b3b38536..b80b223eb0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -64,8 +64,8 @@ "@storybook/test": "^8.2.7", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "buffer": "^6.0.3", "chokidar": "3.6.0", "eslint": "^8.57.0", diff --git a/frontend/src/components/CodeEditor.tsx b/frontend/src/components/CodeEditor.tsx index 6589f3b3cc..963e4cfc11 100644 --- a/frontend/src/components/CodeEditor.tsx +++ b/frontend/src/components/CodeEditor.tsx @@ -64,7 +64,9 @@ export const CodeEditor = ( const handleEditorTextChange = useCallback((state: EditorState) => { const currentText = state.doc.toString() - onTextChanged && onTextChanged(currentText) + if (onTextChanged) { + onTextChanged(currentText) + } }, [onTextChanged]) useEffect(() => { diff --git a/frontend/src/features/graph/create-layout.ts b/frontend/src/features/graph/create-layout.ts index 6ad9b5d5e6..354b78d87b 100644 --- a/frontend/src/features/graph/create-layout.ts +++ b/frontend/src/features/graph/create-layout.ts @@ -108,8 +108,6 @@ export const layoutNodes = (modules: Module[], topology: Topology | undefined) = style: { stroke: 'rgb(251 113 133)' }, animated: true, }) - call.name - call.module } }), ) From bf981b04dde3791b792d4abbac0c0ab9d3274185 Mon Sep 17 00:00:00 2001 From: worstell Date: Mon, 12 Aug 2024 11:39:47 -0700 Subject: [PATCH 18/35] fix: possible race in reset subscription (#2301) only update cursor, leave state as-is fixes #2261 --- backend/controller/sql/queries.sql | 3 +-- backend/controller/sql/queries.sql.go | 3 +-- lsp/hoveritems.go | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/backend/controller/sql/queries.sql b/backend/controller/sql/queries.sql index 031a46e964..10854ad72e 100644 --- a/backend/controller/sql/queries.sql +++ b/backend/controller/sql/queries.sql @@ -866,8 +866,7 @@ WITH event AS ( WHERE "key" = $2::topic_event_key ) UPDATE topic_subscriptions -SET state = 'idle', - cursor = (SELECT id FROM event) +SET cursor = (SELECT id FROM event) WHERE key = $1::subscription_key; -- name: GetTopic :one diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index 224402327f..a9116d5b4c 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -2413,8 +2413,7 @@ WITH event AS ( WHERE "key" = $2::topic_event_key ) UPDATE topic_subscriptions -SET state = 'idle', - cursor = (SELECT id FROM event) +SET cursor = (SELECT id FROM event) WHERE key = $1::subscription_key ` diff --git a/lsp/hoveritems.go b/lsp/hoveritems.go index ddd63c82ec..db9ad3c6ac 100644 --- a/lsp/hoveritems.go +++ b/lsp/hoveritems.go @@ -5,7 +5,7 @@ var hoverMap = map[string]string{ "//ftl:cron": "## Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n### Examples\n\nThe following function will be called hourly:\n\n```go\n//ftl:cron 0 * * * *\nfunc Hourly(ctx context.Context) error {\n // ...\n}\n```\n\nEvery 12 hours, starting at UTC midnight:\n\n```go\n//ftl:cron 12h\nfunc TwiceADay(ctx context.Context) error {\n // ...\n}\n```\n\nEvery Monday at UTC midnight:\n\n```go\n//ftl:cron Mon\nfunc Mondays(ctx context.Context) error {\n // ...\n}\n```\n\n", "//ftl:enum": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system, but aren't directly supported by Go. However they can be approximated with the use of [sealed interfaces](https://blog.chewxy.com/2018/03/18/golang-interfaces/). To declare a sum type in FTL use the comment directive `//ftl:enum`:\n\n```go\n//ftl:enum\ntype Animal interface { animal() }\n\ntype Cat struct {}\nfunc (Cat) animal() {}\n\ntype Dog struct {}\nfunc (Dog) animal() {}\n```\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n```go\n//ftl:enum\ntype Colour string\n\nconst (\n Red Colour = \"red\"\n Green Colour = \"green\"\n Blue Colour = \"blue\"\n)\n```\n", "//ftl:ingress": "## HTTP Ingress\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequest struct {\n\tUserID string `json:\"userId\"`\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[GetRequest]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n // ...\n}\n```\n\n> **NOTE!**\n> The `req` and `resp` types of HTTP `ingress` [verbs](../verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n>\n> You will need to import `ftl/builtin`.\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n## Field mapping\n\nGiven the following request verb:\n\n```go\ntype GetRequest struct {\n\tUserID string `json:\"userId\"`\n\tTag ftl.Option[string] `json:\"tag\"`\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress http GET /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[GetRequest]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.Body.UserID, req.Body.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\n`path`, `query`, and `body` parameters are automatically mapped to the `req` structure.\n\nFor example, this curl request will map `userId` to `req.Body.UserID` and `postId` to `req.Body.PostID`, and `tag` to `req.Body.Tag`:\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456?tag=ftl\n```\n\nThe response here will be:\n\n```json\n{\n \"msg\": \"UserID: 123, PostID: 456, Tag: ftl\"\n}\n```\n\n#### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n#### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n## SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http GET /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X GET \"http://localhost:8891/typeenum\" \\\n -H \"Content-Type: application/json\" \\\n --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n \"name\": \"A\",\n \"value\": \"sample\"\n}\n```\n\n## Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n", - "//ftl:retry": "## Retries\n\nAny verb called asynchronously (specifically, PubSub subscribers and FSM states), may optionally specify a basic exponential backoff retry policy via a Go comment directive. The directive has the following syntax:\n\n```go\n//ftl:retry [] []\n```\n\n`attempts` and `max-backoff` default to unlimited if not specified.\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```go\n//ftl:retry 10 5s 1m\nfunc Invoiced(ctx context.Context, in Invoice) error {\n // ...\n}\n```\n", + "//ftl:retry": "## Retries\n\nAny verb called asynchronously (specifically, PubSub subscribers and FSM states), may optionally specify a basic exponential backoff retry policy via a Go comment directive. The directive has the following syntax:\n\n```go\n//ftl:retry [] [] [catch ]\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```go\n//ftl:retry 10 5s 1m\nfunc Invoiced(ctx context.Context, in Invoice) error {\n // ...\n}\n```\n\n## Catching\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `builtin.CatchRequest` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```go\n//ftl retry 5 1s catch recoverPaymentProcessing\nfunc ProcessPayment(ctx context.Context, payment Payment) error {\n ...\n}\n\n//ftl:verb\nfunc RecoverPaymentProcessing(ctx context.Context, request builtin.CatchRequest[Payment]) error {\n // safely handle final failure of the payment\n}\n```\n\nFor FSMs, after a catch verb has been successfully called the FSM will moved to the failed state.", "//ftl:subscribe": "## PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent), subscriptions (a cursor over the topic), and subscribers (functions events are delivered to). Subscribers are, as you would expect, sinks. Each subscription is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each subscription may have multiple subscribers, in which case events will be distributed among them.\n\nFirst, declare a new topic:\n\n```go\nvar Invoices = ftl.Topic[Invoice](\"invoices\")\n```\n\nThen declare each subscription on the topic:\n\n```go\nvar _ = ftl.Subscription(Invoices, \"emailInvoices\")\n```\n\nAnd finally define a Sink to consume from the subscription:\n\n```go\n//ftl:subscribe emailInvoices\nfunc SendInvoiceEmail(ctx context.Context, in Invoice) error {\n // ...\n}\n```\n\nEvents can be published to a topic like so:\n\n```go\nInvoices.Publish(ctx, Invoice{...})\n```\n\n> **NOTE!**\n> PubSub topics cannot be published to from outside the module that declared them, they can only be subscribed to. That is, if a topic is declared in module `A`, module `B` cannot publish to it.\n", "//ftl:typealias": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n```go\n//ftl:typealias\ntype Alias Target\n```\nor\n```go\n//ftl:typealias\ntype Alias = Target\n```\n\neg.\n\n```go\n//ftl:typealias\ntype UserID string\n\n//ftl:typealias\ntype UserToken = string\n```\n", "//ftl:verb": "## Verbs\n\n## Defining Verbs\n\nTo declare a Verb, write a normal Go function with the following signature, annotated with the Go [comment directive](https://tip.golang.org/doc/comment#syntax) `//ftl:verb`:\n\n```go\n//ftl:verb\nfunc F(context.Context, In) (Out, error) { }\n```\n\neg.\n\n```go\ntype EchoRequest struct {}\n\ntype EchoResponse struct {}\n\n//ftl:verb\nfunc Echo(ctx context.Context, in EchoRequest) (EchoResponse, error) {\n // ...\n}\n```\n\nBy default verbs are only [visible](../visibility) to other verbs in the same module.\n\n## Calling Verbs\n\nTo call a verb use `ftl.Call()`. eg.\n\n```go\nout, err := ftl.Call(ctx, echo.Echo, echo.EchoRequest{})\n```\n", From 477fa3a75119d79779b9c58f852db508890a6e3e Mon Sep 17 00:00:00 2001 From: Wes Date: Mon, 12 Aug 2024 13:58:54 -0700 Subject: [PATCH 19/35] chore: update types docs for Unit and Empty (#2330) --- docs/content/docs/reference/types.md | 69 ++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/content/docs/reference/types.md b/docs/content/docs/reference/types.md index af7eb8350a..1971df7585 100644 --- a/docs/content/docs/reference/types.md +++ b/docs/content/docs/reference/types.md @@ -85,3 +85,72 @@ type UserToken = string --- +## Optional types + +FTL supports optional types, which are types that can be `None` or `Some` and can be declared via `ftl.Option[T]`. These types are provided by the `ftl` runtimes. For example, the following FTL type declaration in go, will provide an optional string type "Name": + +```go +type EchoResponse struct { + Name ftl.Option[string] `json:"name"` +} +``` + +The value of this type can be set to `Some` or `None`: + +```go +resp := EchoResponse{ + Name: ftl.Some("John"), +} + +resp := EchoResponse{ + Name: ftl.None(), +} +``` + +The value of the optional type can be accessed using `Get`, `MustGet`, or `Default` methods: + +```go +// Get returns the value and a boolean indicating if the Option contains a value. +if value, ok := resp.Name.Get(); ok { + resp.Name = ftl.Some(value) +} + +// MustGet returns the value or panics if the Option is None. +value := resp.Name.MustGet() + +// Default returns the value or a default value if the Option is None. +value := resp.Name.Default("default") +``` + +## Unit "void" type + +The `Unit` type is similar to the `void` type in other languages. It is used to indicate that a function does not return a value. For example: + +```go +//ftl:ingress GET /unit +func Unit(ctx context.Context, req builtin.HttpRequest[TimeRequest]) (builtin.HttpResponse[ftl.Unit, string], error) { + return builtin.HttpResponse[ftl.Unit, string]{Body: ftl.Some(ftl.Unit{})}, nil +} +``` + +This request will return an empty body with a status code of 200: + +```sh +curl http://localhost:8891/unit -i +``` + +```http +HTTP/1.1 200 OK +Date: Mon, 12 Aug 2024 17:58:22 GMT +Content-Length: 0 +``` + +## Builtin types + +FTL provides a set of builtin types that are automatically available in all FTL runtimes. These types are: + +- `builtin.HttpRequest[Body]` - Represents an HTTP request with a body of type `Body`. +- `builtin.HttpResponse[Body, Error]` - Represents an HTTP response with a body of type `Body` and an error of type `Error`. +- `builtin.Empty` - Represents an empty type. This equates to an empty structure `{}`. +- `builtin.CatchRequest` - Represents a request structure for catch verbs. + From 4570d939880b3de53781ee287af8dacbe58cf3ae Mon Sep 17 00:00:00 2001 From: Safeer Jiwan Date: Mon, 12 Aug 2024 14:13:31 -0700 Subject: [PATCH 20/35] feat: otel metrics for ingress (#2310) ``` InstrumentationScope ftl.ingress Metric #0 Descriptor: -> Name: ftl.ingress.requests -> Description: the number of ingress requests that the FTL controller receives -> Unit: 1 -> DataType: Sum -> IsMonotonic: true -> AggregationTemporality: Cumulative NumberDataPoints #0 Data point attributes: -> ftl.ingress.method: Str(GET) -> ftl.ingress.path: Str(/http/echo) -> ftl.ingress.run_time_ms.bucket: Str([16,32)) -> ftl.ingress.verb.ref: Str(echo.getEcho) -> ftl.module.name: Str(echo) StartTimestamp: 2024-08-12 17:44:51.923107 +0000 UTC Timestamp: 2024-08-12 17:45:26.923594 +0000 UTC Value: 1 Metric #1 Descriptor: -> Name: ftl.ingress.ms_to_complete -> Description: duration in ms to complete an ingress request -> Unit: ms -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 Data point attributes: -> ftl.ingress.method: Str(GET) -> ftl.ingress.path: Str(/http/echo) -> ftl.ingress.verb.ref: Str(echo.getEcho) -> ftl.module.name: Str(echo) StartTimestamp: 2024-08-12 17:44:51.92311 +0000 UTC Timestamp: 2024-08-12 17:45:26.923622 +0000 UTC Count: 1 Sum: 27.000000 Min: 27.000000 Max: 27.000000 ``` --------- Co-authored-by: github-actions[bot] --- backend/controller/controller.go | 7 +- backend/controller/ingress/handler.go | 21 ++++- backend/controller/ingress/handler_test.go | 3 +- backend/controller/observability/ingress.go | 76 +++++++++++++++++++ .../controller/observability/observability.go | 3 + 5 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 backend/controller/observability/ingress.go diff --git a/backend/controller/controller.go b/backend/controller/controller.go index fa329ead78..0ef15118de 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -339,22 +339,27 @@ func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling } func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { + start := time.Now() + routes, err := s.dal.GetIngressRoutes(r.Context(), r.Method) if err != nil { if errors.Is(err, dalerrs.ErrNotFound) { http.NotFound(w, r) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), start, optional.Some("route not found in dal")) return } http.Error(w, err.Error(), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), start, optional.Some("failed to resolve route from dal")) return } sch, err := s.dal.GetActiveSchema(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), start, optional.Some("could not get active schema")) return } requestKey := model.NewRequestKey(model.OriginIngress, fmt.Sprintf("%s %s", r.Method, r.URL.Path)) - ingress.Handle(sch, requestKey, routes, w, r, s.callWithRequest) + ingress.Handle(start, sch, requestKey, routes, w, r, s.callWithRequest) } func (s *Service) ProcessList(ctx context.Context, req *connect.Request[ftlv1.ProcessListRequest]) (*connect.Response[ftlv1.ProcessListResponse], error) { diff --git a/backend/controller/ingress/handler.go b/backend/controller/ingress/handler.go index 3201bb9767..47207dacc0 100644 --- a/backend/controller/ingress/handler.go +++ b/backend/controller/ingress/handler.go @@ -5,11 +5,13 @@ import ( "encoding/json" "errors" "net/http" + "time" "connectrpc.com/connect" "github.com/alecthomas/types/optional" "github.com/TBD54566975/ftl/backend/controller/dal" + "github.com/TBD54566975/ftl/backend/controller/observability" dalerrs "github.com/TBD54566975/ftl/backend/dal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" @@ -20,6 +22,7 @@ import ( // Handle HTTP ingress routes. func Handle( + startTime time.Time, sch *schema.Schema, requestKey model.RequestKey, routes []dal.IngressRoute, @@ -33,24 +36,29 @@ func Handle( if err != nil { if errors.Is(err, dalerrs.ErrNotFound) { http.NotFound(w, r) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), startTime, optional.Some("route not found")) return } logger.Errorf(err, "failed to resolve route for %s %s", r.Method, r.URL.Path) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), startTime, optional.Some("failed to resolve route")) return } + verbRef := &schemapb.Ref{Module: route.Module, Name: route.Verb} + body, err := BuildRequestBody(route, r, sch) if err != nil { // Only log at debug, as this is a client side error logger.Debugf("bad request: %s", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("bad request")) return } creq := connect.NewRequest(&ftlv1.CallRequest{ Metadata: &ftlv1.Metadata{}, - Verb: &schemapb.Ref{Module: route.Module, Name: route.Verb}, + Verb: verbRef, Body: body, }) @@ -60,8 +68,10 @@ func Handle( if connectErr := new(connect.Error); errors.As(err, &connectErr) { httpCode := connectCodeToHTTP(connectErr.Code()) http.Error(w, http.StatusText(httpCode), httpCode) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("failed to call verb: connect error")) } else { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("failed to call verb: internal server error")) } return } @@ -72,6 +82,7 @@ func Handle( if err != nil { logger.Errorf(err, "could not resolve schema type for verb %s", route.Verb) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("could not resolve schema type for verb")) return } var responseBody []byte @@ -81,6 +92,7 @@ func Handle( if err := json.Unmarshal(msg.Body, &response); err != nil { logger.Errorf(err, "could not unmarhal response for verb %s", verb) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("could not unmarhal response for verb")) return } @@ -89,6 +101,7 @@ func Handle( if err != nil { logger.Errorf(err, "could not create response for verb %s", verb) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("could not create response for verb")) return } @@ -105,12 +118,16 @@ func Handle( responseBody = msg.Body } _, err = w.Write(responseBody) - if err != nil { + if err == nil { + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.None[string]()) + } else { logger.Errorf(err, "Could not write response body") + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("could not write response body")) } case *ftlv1.CallResponse_Error_: http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.Some(verbRef), startTime, optional.Some("call response: internal server error")) } } diff --git a/backend/controller/ingress/handler_test.go b/backend/controller/ingress/handler_test.go index 527992c04d..7251e88860 100644 --- a/backend/controller/ingress/handler_test.go +++ b/backend/controller/ingress/handler_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "net/url" "testing" + "time" "connectrpc.com/connect" "github.com/alecthomas/assert/v2" @@ -99,7 +100,7 @@ func TestIngress(t *testing.T) { req := httptest.NewRequest(test.method, test.path, bytes.NewBuffer(test.payload)).WithContext(ctx) req.URL.RawQuery = test.query.Encode() reqKey := model.NewRequestKey(model.OriginIngress, "test") - ingress.Handle(sch, reqKey, routes, rec, req, func(ctx context.Context, r *connect.Request[ftlv1.CallRequest], requestKey optional.Option[model.RequestKey], parentRequestKey optional.Option[model.RequestKey], requestSource string) (*connect.Response[ftlv1.CallResponse], error) { + ingress.Handle(time.Now(), sch, reqKey, routes, rec, req, func(ctx context.Context, r *connect.Request[ftlv1.CallRequest], requestKey optional.Option[model.RequestKey], parentRequestKey optional.Option[model.RequestKey], requestSource string) (*connect.Response[ftlv1.CallResponse], error) { body, err := encoding.Marshal(response) assert.NoError(t, err) return connect.NewResponse(&ftlv1.CallResponse{Response: &ftlv1.CallResponse_Body{Body: body}}), nil diff --git a/backend/controller/observability/ingress.go b/backend/controller/observability/ingress.go new file mode 100644 index 0000000000..ebae91ad80 --- /dev/null +++ b/backend/controller/observability/ingress.go @@ -0,0 +1,76 @@ +package observability + +import ( + "context" + "fmt" + "time" + + "github.com/alecthomas/types/optional" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + + schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" + "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/observability" +) + +const ( + ingressMeterName = "ftl.ingress" + ingressMethodAttr = "ftl.ingress.method" + ingressPathAttr = "ftl.ingress.path" + ingressVerbRefAttr = "ftl.ingress.verb.ref" + ingressFailureModeAttr = "ftl.ingress.failure_mode" + ingressRunTimeBucketAttr = "ftl.ingress.run_time_ms.bucket" +) + +type IngressMetrics struct { + requests metric.Int64Counter + msToComplete metric.Int64Histogram +} + +func initIngressMetrics() (*IngressMetrics, error) { + result := &IngressMetrics{ + requests: noop.Int64Counter{}, + msToComplete: noop.Int64Histogram{}, + } + + var err error + meter := otel.Meter(ingressMeterName) + + signalName := fmt.Sprintf("%s.requests", ingressMeterName) + if result.requests, err = meter.Int64Counter(signalName, metric.WithUnit("1"), + metric.WithDescription("the number of ingress requests that the FTL controller receives")); err != nil { + return nil, wrapErr(signalName, err) + } + + signalName = fmt.Sprintf("%s.ms_to_complete", ingressMeterName) + if result.msToComplete, err = meter.Int64Histogram(signalName, metric.WithUnit("ms"), + metric.WithDescription("duration in ms to complete an ingress request")); err != nil { + return nil, wrapErr(signalName, err) + } + + return result, nil +} + +func (m *IngressMetrics) Request(ctx context.Context, method string, path string, verb optional.Option[*schemapb.Ref], startTime time.Time, failureMode optional.Option[string]) { + attrs := []attribute.KeyValue{ + attribute.String(ingressMethodAttr, method), + attribute.String(ingressPathAttr, path), + } + if v, ok := verb.Get(); ok { + attrs = append(attrs, + attribute.String(observability.ModuleNameAttribute, v.Module), + attribute.String(ingressVerbRefAttr, schema.RefFromProto(v).String())) + } + if f, ok := failureMode.Get(); ok { + attrs = append(attrs, attribute.String(ingressFailureModeAttr, f)) + } + + msToComplete := timeSinceMS(startTime) + m.msToComplete.Record(ctx, msToComplete, metric.WithAttributes(attrs...)) + + attrs = append(attrs, attribute.String(ingressRunTimeBucketAttr, logBucket(2, msToComplete))) + m.requests.Add(ctx, 1, metric.WithAttributes(attrs...)) +} diff --git a/backend/controller/observability/observability.go b/backend/controller/observability/observability.go index ca952c2fb7..57851b0e0e 100644 --- a/backend/controller/observability/observability.go +++ b/backend/controller/observability/observability.go @@ -12,6 +12,7 @@ var ( Calls *CallMetrics Deployment *DeploymentMetrics FSM *FSMMetrics + Ingress *IngressMetrics PubSub *PubSubMetrics Cron *CronMetrics ) @@ -28,6 +29,8 @@ func init() { errs = errors.Join(errs, err) FSM, err = initFSMMetrics() errs = errors.Join(errs, err) + Ingress, err = initIngressMetrics() + errs = errors.Join(errs, err) PubSub, err = initPubSubMetrics() errs = errors.Join(errs, err) Cron, err = initCronMetrics() From 7b6a42160b8bfa80098cc867f0f78ecc1f641f82 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Tue, 13 Aug 2024 11:31:51 +1000 Subject: [PATCH 21/35] feat: Initial Java runtime implementation (#2318) This is still very much a work in progress, however it contains a lot of basic functionality. So far this includes support for: - Verb invocations - HTTP ingress - Cron - Topics and Subscriptions - Basic testing of Verbs The existing Kotlin example has been migrated over to the new approach. At the moment the module is called Java even though it supports both, in future this will provide a base layer of functionality with some small language dependent features in separate Java/Kotlin modules. --- Justfile | 6 +- .../scaling/localscaling/local_scaling.go | 2 +- backend/runner/runner.go | 2 +- backend/schema/metadatatypemap.go | 2 +- buildengine/build.go | 2 + buildengine/build_java.go | 23 + buildengine/build_kotlin.go | 4 +- buildengine/build_test.go | 2 +- buildengine/deps.go | 52 ++ buildengine/discover_test.go | 4 +- buildengine/stubs.go | 41 +- buildengine/stubs_test.go | 7 +- common/moduleconfig/moduleconfig.go | 31 +- deployment/base/ftl-runner/ftl-runner.yml | 2 +- examples/go/echo/echo.go | 2 +- examples/kotlin/echo/ftl.toml | 2 +- examples/kotlin/echo/pom.xml | 309 ++++---- .../src/main/ftl-module-schema/builtin.pb | Bin 0 -> 832 bytes .../echo/src/main/ftl-module-schema/time.pb | Bin 0 -> 96 bytes .../echo/src/main/kotlin/ftl/echo/Echo.kt | 13 +- examples/kotlin/time/ftl.toml | 2 +- examples/kotlin/time/pom.xml | 309 ++++---- .../time/src/main/kotlin/ftl/time/Time.kt | 6 +- ftl-project.toml | 3 + go-runtime/compile/build.go | 25 +- go-runtime/schema/common/directive.go | 2 +- java-runtime/.gitignore | 6 + java-runtime/README.md | 22 + java-runtime/ftl-runtime/deployment/pom.xml | 60 ++ .../ftl/deployment/FTLCodeGenerator.java | 349 +++++++++ .../block/ftl/deployment/FtlProcessor.java | 696 ++++++++++++++++++ .../ftl/deployment/ModuleNameBuildItem.java | 16 + .../xyz/block/ftl/deployment/RetryRecord.java | 19 + .../SubscriptionMetaAnnotationsBuildItem.java | 35 + .../block/ftl/deployment/TopicsBuildItem.java | 26 + .../block/ftl/deployment/TopicsProcessor.java | 97 +++ .../ftl/deployment/VerbClientBuildItem.java | 25 + .../ftl/deployment/VerbClientsProcessor.java | 212 ++++++ .../io.quarkus.deployment.CodeGenProvider | 1 + .../test/FtlJavaRuntimeDevModeTest.java | 25 + .../java/runtime/test/FtlJavaRuntimeTest.java | 25 + .../ftl-runtime/integration-tests/pom.xml | 98 +++ .../src/main/ftl-module-schema/builtin.pb | Bin 0 -> 832 bytes .../src/main/ftl-module-schema/echo.pb | Bin 0 -> 1440 bytes .../src/main/ftl-module-schema/time.pb | Bin 0 -> 695 bytes .../runtime/it/FtlJavaRuntimeResource.java | 46 ++ .../block/ftl/java/runtime/it/MyTopic.java | 10 + .../xyz/block/ftl/java/runtime/it/Person.java | 5 + .../src/main/resources/application.properties | 0 .../it/FtlJavaRuntimeResourceTest.java | 62 ++ java-runtime/ftl-runtime/pom.xml | 264 +++++++ java-runtime/ftl-runtime/runtime/pom.xml | 137 ++++ .../src/main/java/xyz/block/ftl/Config.java | 12 + .../src/main/java/xyz/block/ftl/Cron.java | 14 + .../src/main/java/xyz/block/ftl/Export.java | 14 + .../main/java/xyz/block/ftl/GeneratedRef.java | 11 + .../src/main/java/xyz/block/ftl/Retry.java | 20 + .../src/main/java/xyz/block/ftl/Secret.java | 12 + .../main/java/xyz/block/ftl/Subscription.java | 28 + .../src/main/java/xyz/block/ftl/Topic.java | 12 + .../java/xyz/block/ftl/TopicDefinition.java | 17 + .../src/main/java/xyz/block/ftl/Verb.java | 15 + .../main/java/xyz/block/ftl/VerbClient.java | 17 + .../xyz/block/ftl/VerbClientDefinition.java | 18 + .../java/xyz/block/ftl/VerbClientEmpty.java | 5 + .../java/xyz/block/ftl/VerbClientSink.java | 5 + .../java/xyz/block/ftl/VerbClientSource.java | 5 + .../src/main/java/xyz/block/ftl/VerbName.java | 12 + .../block/ftl/runtime/FTLConfigSource.java | 65 ++ .../xyz/block/ftl/runtime/FTLController.java | 182 +++++ .../xyz/block/ftl/runtime/FTLHttpHandler.java | 245 ++++++ .../xyz/block/ftl/runtime/FTLRecorder.java | 110 +++ .../xyz/block/ftl/runtime/TopicHelper.java | 32 + .../block/ftl/runtime/VerbClientHelper.java | 48 ++ .../xyz/block/ftl/runtime/VerbHandler.java | 51 ++ .../xyz/block/ftl/runtime/VerbInvoker.java | 9 + .../xyz/block/ftl/runtime/VerbRegistry.java | 179 +++++ .../ftl/runtime/builtin/HttpRequest.java | 66 ++ .../ftl/runtime/builtin/HttpResponse.java | 49 ++ .../resources/META-INF/quarkus-extension.yaml | 9 + ...lipse.microprofile.config.spi.ConfigSource | 1 + .../ftl-runtime/test-framework/pom.xml | 32 + .../xyz/block/ftl/java/test/FTLManaged.java | 8 + .../java/xyz/block/ftl/java/test/TestFTL.java | 16 + .../java/test/internal/FTLTestResource.java | 27 + .../ftl/java/test/internal/FTLTestServer.java | 33 + .../java/test/internal/TestVerbServer.java | 109 +++ .../src/main/resources/application.properties | 0 88 files changed, 4228 insertions(+), 349 deletions(-) create mode 100644 buildengine/build_java.go create mode 100644 examples/kotlin/echo/src/main/ftl-module-schema/builtin.pb create mode 100644 examples/kotlin/echo/src/main/ftl-module-schema/time.pb create mode 100644 java-runtime/.gitignore create mode 100644 java-runtime/README.md create mode 100644 java-runtime/ftl-runtime/deployment/pom.xml create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/ModuleNameBuildItem.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/RetryRecord.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/SubscriptionMetaAnnotationsBuildItem.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsBuildItem.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsProcessor.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientBuildItem.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientsProcessor.java create mode 100644 java-runtime/ftl-runtime/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider create mode 100644 java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeDevModeTest.java create mode 100644 java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeTest.java create mode 100644 java-runtime/ftl-runtime/integration-tests/pom.xml create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/builtin.pb create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/echo.pb create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/time.pb create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/FtlJavaRuntimeResource.java create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/MyTopic.java create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/Person.java create mode 100644 java-runtime/ftl-runtime/integration-tests/src/main/resources/application.properties create mode 100644 java-runtime/ftl-runtime/integration-tests/src/test/java/xyz/block/ftl/java/runtime/it/FtlJavaRuntimeResourceTest.java create mode 100644 java-runtime/ftl-runtime/pom.xml create mode 100644 java-runtime/ftl-runtime/runtime/pom.xml create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Config.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Cron.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Export.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/GeneratedRef.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Retry.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Secret.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Subscription.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Topic.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/TopicDefinition.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Verb.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClient.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbName.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLConfigSource.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLHttpHandler.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/TopicHelper.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbClientHelper.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbInvoker.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpRequest.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpResponse.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/quarkus-extension.yaml create mode 100644 java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource create mode 100644 java-runtime/ftl-runtime/test-framework/pom.xml create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/FTLManaged.java create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/TestFTL.java create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestResource.java create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestServer.java create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/TestVerbServer.java create mode 100644 java-runtime/ftl-runtime/test-framework/src/main/resources/application.properties diff --git a/Justfile b/Justfile index 01acf1b203..1d1441cc7a 100644 --- a/Justfile +++ b/Justfile @@ -31,6 +31,7 @@ clean: rm -rf frontend/node_modules find . -name '*.zip' -exec rm {} \; mvn -f kotlin-runtime/ftl-runtime clean + mvn -f java-runtime/ftl-runtime clean # Live rebuild the ftl binary whenever source changes. live-rebuild: @@ -41,7 +42,7 @@ dev *args: watchexec -r {{WATCHEXEC_ARGS}} -- "just build-sqlc && ftl dev {{args}}" # Build everything -build-all: build-protos-unconditionally build-frontend build-generate build-sqlc build-zips lsp-generate +build-all: build-protos-unconditionally build-frontend build-generate build-sqlc build-zips lsp-generate build-java @just build ftl ftl-controller ftl-runner ftl-initdb # Run "go generate" on all packages @@ -64,6 +65,9 @@ build +tools: build-protos build-zips build-frontend build-backend: just build ftl ftl-controller ftl-runner +build-java: + mvn -f java-runtime/ftl-runtime install + export DATABASE_URL := "postgres://postgres:secret@localhost:15432/ftl?sslmode=disable" # Explicitly initialise the database diff --git a/backend/controller/scaling/localscaling/local_scaling.go b/backend/controller/scaling/localscaling/local_scaling.go index f8ba1850ae..99eaf1bb7d 100644 --- a/backend/controller/scaling/localscaling/local_scaling.go +++ b/backend/controller/scaling/localscaling/local_scaling.go @@ -92,7 +92,7 @@ func (l *LocalScaling) SetReplicas(ctx context.Context, replicas int, idleRunner simpleName := fmt.Sprintf("runner%d", keySuffix) if err := kong.ApplyDefaults(&config, kong.Vars{ "deploymentdir": filepath.Join(l.cacheDir, "ftl-runner", simpleName, "deployments"), - "language": "go,kotlin,rust", + "language": "go,kotlin,rust,java", }); err != nil { return err } diff --git a/backend/runner/runner.go b/backend/runner/runner.go index fc68bb8b6a..d48d0c8636 100644 --- a/backend/runner/runner.go +++ b/backend/runner/runner.go @@ -49,7 +49,7 @@ type Config struct { TemplateDir string `help:"Template directory to copy into each deployment, if any." type:"existingdir"` DeploymentDir string `help:"Directory to store deployments in." default:"${deploymentdir}"` DeploymentKeepHistory int `help:"Number of deployments to keep history for." default:"3"` - Language []string `short:"l" help:"Languages the runner supports." env:"FTL_LANGUAGE" default:"go,kotlin,rust"` + Language []string `short:"l" help:"Languages the runner supports." env:"FTL_LANGUAGE" default:"go,kotlin,rust,java"` HeartbeatPeriod time.Duration `help:"Minimum period between heartbeats." default:"3s"` HeartbeatJitter time.Duration `help:"Jitter to add to heartbeat period." default:"2s"` RunnerStartDelay time.Duration `help:"Time in seconds for a runner to wait before contacting the controller. This can be needed in istio environments to work around initialization races." env:"FTL_RUNNER_START_DELAY" default:"0s"` diff --git a/backend/schema/metadatatypemap.go b/backend/schema/metadatatypemap.go index 432fd4f3c3..997e16c952 100644 --- a/backend/schema/metadatatypemap.go +++ b/backend/schema/metadatatypemap.go @@ -11,7 +11,7 @@ import ( type MetadataTypeMap struct { Pos Position `parser:"" protobuf:"1,optional"` - Runtime string `parser:"'+' 'typemap' @('go' | 'kotlin')" protobuf:"2"` + Runtime string `parser:"'+' 'typemap' @('go' | 'kotlin' | 'java')" protobuf:"2"` NativeName string `parser:"@String" protobuf:"3"` } diff --git a/buildengine/build.go b/buildengine/build.go index a2a32a43df..aff120ed65 100644 --- a/buildengine/build.go +++ b/buildengine/build.go @@ -47,6 +47,8 @@ func buildModule(ctx context.Context, projectRootDir string, sch *schema.Schema, switch module.Config.Language { case "go": err = buildGoModule(ctx, projectRootDir, sch, module, filesTransaction) + case "java": + err = buildJavaModule(ctx, module) case "kotlin": err = buildKotlinModule(ctx, sch, module) case "rust": diff --git a/buildengine/build_java.go b/buildengine/build_java.go new file mode 100644 index 0000000000..57b3d79c44 --- /dev/null +++ b/buildengine/build_java.go @@ -0,0 +1,23 @@ +package buildengine + +import ( + "context" + "fmt" + + "github.com/TBD54566975/ftl/internal/exec" + "github.com/TBD54566975/ftl/internal/log" +) + +func buildJavaModule(ctx context.Context, module Module) error { + logger := log.FromContext(ctx) + if err := SetPOMProperties(ctx, module.Config.Dir); err != nil { + return fmt.Errorf("unable to update ftl.version in %s: %w", module.Config.Dir, err) + } + logger.Infof("Using build command '%s'", module.Config.Build) + err := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build).RunBuffered(ctx) + if err != nil { + return fmt.Errorf("failed to build module %q: %w", module.Config.Module, err) + } + + return nil +} diff --git a/buildengine/build_kotlin.go b/buildengine/build_kotlin.go index 595976186f..5e81c1664c 100644 --- a/buildengine/build_kotlin.go +++ b/buildengine/build_kotlin.go @@ -43,16 +43,14 @@ func buildKotlinModule(ctx context.Context, sch *schema.Schema, module Module) e if err := SetPOMProperties(ctx, module.Config.Dir); err != nil { return fmt.Errorf("unable to update ftl.version in %s: %w", module.Config.Dir, err) } - if err := generateExternalModules(ctx, module, sch); err != nil { return fmt.Errorf("unable to generate external modules for %s: %w", module.Config.Module, err) } - if err := prepareFTLRoot(module); err != nil { return fmt.Errorf("unable to prepare FTL root for %s: %w", module.Config.Module, err) } - logger.Debugf("Using build command '%s'", module.Config.Build) + logger.Infof("Using build command '%s'", module.Config.Build) err := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build).RunBuffered(ctx) if err != nil { return fmt.Errorf("failed to build module %q: %w", module.Config.Module, err) diff --git a/buildengine/build_test.go b/buildengine/build_test.go index e29e244ea2..fba4cf4089 100644 --- a/buildengine/build_test.go +++ b/buildengine/build_test.go @@ -93,7 +93,7 @@ func testBuildClearsBuildDir(t *testing.T, bctx buildContext) { projectRoot := t.TempDir() // generate stubs to create the shared modules directory - err = GenerateStubs(ctx, projectRoot, bctx.sch.Modules, []moduleconfig.ModuleConfig{{Dir: bctx.moduleDir}}) + err = GenerateStubs(ctx, projectRoot, bctx.sch.Modules, []moduleconfig.ModuleConfig{{Dir: bctx.moduleDir, Language: "go"}}) assert.NoError(t, err) // build to generate the build directory diff --git a/buildengine/deps.go b/buildengine/deps.go index c989c45fc7..2f4bf4a5a1 100644 --- a/buildengine/deps.go +++ b/buildengine/deps.go @@ -51,6 +51,9 @@ func extractDependencies(module Module) ([]string, error) { case "kotlin": return extractKotlinFTLImports(module.Config.Module, module.Config.Dir) + case "java": + return extractJavaFTLImports(module.Config.Module, module.Config.Dir) + case "rust": return extractRustFTLImports(module.Config.Module, module.Config.Dir) @@ -140,6 +143,55 @@ func extractKotlinFTLImports(self, dir string) ([]string, error) { return modules, nil } +func extractJavaFTLImports(self, dir string) ([]string, error) { + dependencies := map[string]bool{} + // We also attempt to look at kotlin files + // As the Java module supports both + kotin, kotlinErr := extractKotlinFTLImports(self, dir) + if kotlinErr == nil { + // We don't really care about the error case, its probably a Java project + for _, imp := range kotin { + dependencies[imp] = true + } + } + javaImportRegex := regexp.MustCompile(`^import ftl\.([A-Za-z0-9_.]+)`) + + err := filepath.WalkDir(filepath.Join(dir, "src/main/java"), func(path string, d fs.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("failed to walk directory: %w", err) + } + if d.IsDir() || !(strings.HasSuffix(path, ".java")) { + return nil + } + file, err := os.Open(path) + if err != nil { + return fmt.Errorf("failed to open file: %w", err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + matches := javaImportRegex.FindStringSubmatch(scanner.Text()) + if len(matches) > 1 { + module := strings.Split(matches[1], ".")[0] + if module == self { + continue + } + dependencies[module] = true + } + } + return scanner.Err() + }) + + // We only error out if they both failed + if err != nil && kotlinErr != nil { + return nil, fmt.Errorf("%s: failed to extract dependencies from Java module: %w", self, err) + } + modules := maps.Keys(dependencies) + sort.Strings(modules) + return modules, nil +} + func extractRustFTLImports(self, dir string) ([]string, error) { fmt.Fprintf(os.Stderr, "RUST TODO extractRustFTLImports\n") diff --git a/buildengine/discover_test.go b/buildengine/discover_test.go index dc7b241daa..26dbb8db02 100644 --- a/buildengine/discover_test.go +++ b/buildengine/discover_test.go @@ -73,7 +73,7 @@ func TestDiscoverModules(t *testing.T) { Language: "kotlin", Realm: "home", Module: "echo", - Build: "mvn -B compile", + Build: "mvn -B package", Deploy: []string{ "main", "classes", @@ -116,7 +116,7 @@ func TestDiscoverModules(t *testing.T) { Language: "kotlin", Realm: "home", Module: "externalkotlin", - Build: "mvn -B compile", + Build: "mvn -B package", Deploy: []string{ "main", "classes", diff --git a/buildengine/stubs.go b/buildengine/stubs.go index 646348b4d4..5992e4ff65 100644 --- a/buildengine/stubs.go +++ b/buildengine/stubs.go @@ -3,6 +3,8 @@ package buildengine import ( "context" "fmt" + "os" + "path/filepath" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/common/moduleconfig" @@ -13,7 +15,11 @@ import ( // // Currently, only Go stubs are supported. Kotlin and other language stubs can be added in the future. func GenerateStubs(ctx context.Context, projectRoot string, modules []*schema.Module, moduleConfigs []moduleconfig.ModuleConfig) error { - return generateGoStubs(ctx, projectRoot, modules, moduleConfigs) + err := generateGoStubs(ctx, projectRoot, modules, moduleConfigs) + if err != nil { + return err + } + return writeGenericSchemaFiles(ctx, projectRoot, modules, moduleConfigs) } // CleanStubs removes all generated stubs. @@ -37,6 +43,39 @@ func generateGoStubs(ctx context.Context, projectRoot string, modules []*schema. return nil } +func writeGenericSchemaFiles(ctx context.Context, projectRoot string, modules []*schema.Module, moduleConfigs []moduleconfig.ModuleConfig) error { + sch := &schema.Schema{Modules: modules} + for _, module := range moduleConfigs { + if module.GeneratedSchemaDir == "" { + continue + } + + modPath := module.Abs().GeneratedSchemaDir + err := os.MkdirAll(modPath, 0750) + if err != nil { + return fmt.Errorf("failed to create directory %s: %w", modPath, err) + } + + for _, mod := range sch.Modules { + if mod.Name == module.Module { + continue + } + data, err := schema.ModuleToBytes(mod) + if err != nil { + return fmt.Errorf("failed to export module schema for module %s %w", mod.Name, err) + } + err = os.WriteFile(filepath.Join(modPath, mod.Name+".pb"), data, 0600) + if err != nil { + return fmt.Errorf("failed to write schema file for module %s %w", mod.Name, err) + } + } + } + err := compile.GenerateStubsForModules(ctx, projectRoot, moduleConfigs, sch) + if err != nil { + return fmt.Errorf("failed to generate go stubs: %w", err) + } + return nil +} func cleanGoStubs(ctx context.Context, projectRoot string) error { err := compile.CleanStubs(ctx, projectRoot) if err != nil { diff --git a/buildengine/stubs_test.go b/buildengine/stubs_test.go index c4c1efe5b5..3f3d32856d 100644 --- a/buildengine/stubs_test.go +++ b/buildengine/stubs_test.go @@ -6,10 +6,11 @@ import ( "path/filepath" "testing" + "github.com/alecthomas/assert/v2" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/common/moduleconfig" "github.com/TBD54566975/ftl/internal/log" - "github.com/alecthomas/assert/v2" ) func TestGenerateGoStubs(t *testing.T) { @@ -180,7 +181,7 @@ func init() { ctx := log.ContextWithNewDefaultLogger(context.Background()) projectRoot := t.TempDir() - err := GenerateStubs(ctx, projectRoot, modules, []moduleconfig.ModuleConfig{}) + err := GenerateStubs(ctx, projectRoot, modules, []moduleconfig.ModuleConfig{{Language: "go"}}) assert.NoError(t, err) generatedPath := filepath.Join(projectRoot, ".ftl/go/modules/other/external_module.go") @@ -240,7 +241,7 @@ func Call(context.Context, Req) (Resp, error) { ` ctx := log.ContextWithNewDefaultLogger(context.Background()) projectRoot := t.TempDir() - err := GenerateStubs(ctx, projectRoot, modules, []moduleconfig.ModuleConfig{}) + err := GenerateStubs(ctx, projectRoot, modules, []moduleconfig.ModuleConfig{{Language: "go"}}) assert.NoError(t, err) generatedPath := filepath.Join(projectRoot, ".ftl/go/modules/test/external_module.go") diff --git a/common/moduleconfig/moduleconfig.go b/common/moduleconfig/moduleconfig.go index 990e96b732..53ff6b2246 100644 --- a/common/moduleconfig/moduleconfig.go +++ b/common/moduleconfig/moduleconfig.go @@ -21,6 +21,9 @@ type ModuleGoConfig struct{} // ModuleKotlinConfig is language-specific configuration for Kotlin modules. type ModuleKotlinConfig struct{} +// ModuleJavaConfig is language-specific configuration for Java modules. +type ModuleJavaConfig struct{} + // ModuleConfig is the configuration for an FTL module. // // Module config files are currently TOML. @@ -37,6 +40,8 @@ type ModuleConfig struct { Deploy []string `toml:"deploy"` // DeployDir is the directory to deploy from, relative to the module directory. DeployDir string `toml:"deploy-dir"` + // GeneratedSchemaDir is the directory to generate protobuf schema files into. These can be picked up by language specific build tools + GeneratedSchemaDir string `toml:"generated-schema-dir"` // Schema is the name of the schema file relative to the DeployDir. Schema string `toml:"schema"` // Errors is the name of the error file relative to the DeployDir. @@ -46,6 +51,7 @@ type ModuleConfig struct { Go ModuleGoConfig `toml:"go,optional"` Kotlin ModuleKotlinConfig `toml:"kotlin,optional"` + Java ModuleJavaConfig `toml:"java,optional"` } // AbsModuleConfig is a ModuleConfig with all paths made absolute. @@ -84,6 +90,12 @@ func (c ModuleConfig) Abs() AbsModuleConfig { if !strings.HasPrefix(clone.DeployDir, clone.Dir) { panic(fmt.Sprintf("deploy-dir %q is not beneath module directory %q", clone.DeployDir, clone.Dir)) } + if clone.GeneratedSchemaDir != "" { + clone.GeneratedSchemaDir = filepath.Clean(filepath.Join(clone.Dir, clone.GeneratedSchemaDir)) + if !strings.HasPrefix(clone.GeneratedSchemaDir, clone.Dir) { + panic(fmt.Sprintf("generated-schema-dir %q is not beneath module directory %q", clone.GeneratedSchemaDir, clone.Dir)) + } + } clone.Schema = filepath.Clean(filepath.Join(clone.DeployDir, clone.Schema)) if !strings.HasPrefix(clone.Schema, clone.DeployDir) { panic(fmt.Sprintf("schema %q is not beneath deploy directory %q", clone.Schema, clone.DeployDir)) @@ -119,7 +131,7 @@ func setConfigDefaults(moduleDir string, config *ModuleConfig) error { switch config.Language { case "kotlin": if config.Build == "" { - config.Build = "mvn -B compile" + config.Build = "mvn -B package" } if config.DeployDir == "" { config.DeployDir = "target" @@ -130,7 +142,22 @@ func setConfigDefaults(moduleDir string, config *ModuleConfig) error { if len(config.Watch) == 0 { config.Watch = []string{"pom.xml", "src/**", "target/generated-sources"} } - + case "java": + if config.Build == "" { + config.Build = "mvn -B package" + } + if config.DeployDir == "" { + config.DeployDir = "target" + } + if config.GeneratedSchemaDir == "" { + config.GeneratedSchemaDir = "src/main/ftl-module-schema" + } + if len(config.Deploy) == 0 { + config.Deploy = []string{"main", "quarkus-app"} + } + if len(config.Watch) == 0 { + config.Watch = []string{"pom.xml", "src/**", "target/generated-sources"} + } case "go": if config.DeployDir == "" { config.DeployDir = ".ftl" diff --git a/deployment/base/ftl-runner/ftl-runner.yml b/deployment/base/ftl-runner/ftl-runner.yml index 365f806fef..71063b0b22 100644 --- a/deployment/base/ftl-runner/ftl-runner.yml +++ b/deployment/base/ftl-runner/ftl-runner.yml @@ -31,7 +31,7 @@ spec: - name: FTL_RUNNER_ADVERTISE value: "http://$(MY_POD_IP):8893" - name: FTL_LANGUAGE - value: "go,kotlin" + value: "go,kotlin,java" ports: - containerPort: 8893 readinessProbe: diff --git a/examples/go/echo/echo.go b/examples/go/echo/echo.go index 233b4850cb..8f4776749f 100644 --- a/examples/go/echo/echo.go +++ b/examples/go/echo/echo.go @@ -23,7 +23,7 @@ type EchoResponse struct { // Echo returns a greeting with the current time. // -//ftl:verb +//ftl:verb export func Echo(ctx context.Context, req EchoRequest) (EchoResponse, error) { tresp, err := ftl.Call(ctx, time.Time, time.TimeRequest{}) if err != nil { diff --git a/examples/kotlin/echo/ftl.toml b/examples/kotlin/echo/ftl.toml index 700b9d8833..de92e831e1 100644 --- a/examples/kotlin/echo/ftl.toml +++ b/examples/kotlin/echo/ftl.toml @@ -1,2 +1,2 @@ module = "echo" -language = "kotlin" +language = "java" diff --git a/examples/kotlin/echo/pom.xml b/examples/kotlin/echo/pom.xml index 3945bbad4d..f4a3a46581 100644 --- a/examples/kotlin/echo/pom.xml +++ b/examples/kotlin/echo/pom.xml @@ -1,185 +1,182 @@ - + 4.0.0 - - ftl + xyz.block.ftl.examples echo - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT 1.0-SNAPSHOT - 1.8 - 1.9.22 - true - ${java.version} - ${java.version} + 3.13.0 + 2.0.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.12.3 + true + 3.2.5 + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} + xyz.block + ftl-java-runtime + 1.0.0-SNAPSHOT - xyz.block - ftl-runtime - ${ftl.version} + io.quarkus + quarkus-kotlin - org.postgresql - postgresql - 42.7.2 + io.quarkus + quarkus-jackson + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-junit5 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + io.rest-assured + kotlin-extensions + test - - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - compile - - compile - - - - ${project.basedir}/src/main/kotlin - - - - - test-compile - - test-compile - - - - ${project.basedir}/src/test/kotlin - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.6.1 - - - - copy-dependencies - compile - - copy-dependencies - - - ${project.build.directory}/dependency - runtime - - - - - build-classpath - compile - - build-classpath - - - ${project.build.directory}/classpath.txt - dependency - - - - build-classpath-property - compile - - build-classpath - - - generated.classpath - ${project.build.directory}/dependency - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/ftl - - - - - - - com.github.ozsie - detekt-maven-plugin - 1.23.5 - - true - ${generated.classpath} - ${java.version} - ${java.home} - ${project.build.directory}/detekt.yml - - - ${project.build.directory}/dependency/ftl-runtime-${ftl.version}.jar - - - ${project.basedir}/src/main/kotlin,${project.build.directory}/generated-sources - - - - compile - - check-with-type-resolution - - - - - - xyz.block - ftl-runtime - ${ftl.version} - - - - - + src/main/kotlin + src/test/kotlin - kotlin-maven-plugin - org.jetbrains.kotlin + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + native-image-agent + + + - org.apache.maven.plugins - maven-dependency-plugin + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + - - org.codehaus.mojo - build-helper-maven-plugin + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + - - com.github.ozsie - detekt-maven-plugin + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + + compile + + + + test-compile + + test-compile + + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + true + 17 + + all-open + + + + + + + + - \ No newline at end of file + + + + native + + + native + + + + false + true + + + + diff --git a/examples/kotlin/echo/src/main/ftl-module-schema/builtin.pb b/examples/kotlin/echo/src/main/ftl-module-schema/builtin.pb new file mode 100644 index 0000000000000000000000000000000000000000..af6286fa85cb5cef958287c4392d7909446742b3 GIT binary patch literal 832 zcmah{O^?$s5T$L>be;6e+ir)nAj{%HfF81(I2IM{fx`+_Lh3DP4T-c(g6$ynZy@nI zK=20{Cn;T|mAH9ko}b=(GsGITp+#q_GQHEU(v0b2Ar$+ROZIN_ehDq^#AcLc!S@#V z)*{yEF?8tbw~^i@AHP)~{jHhLp4criD_k zZ#J9T2h^2H>??`YJk35!q10Kad!u#H7z{k*vSCiGRlYxlfK?ZjbPqx&`M#0T1uwk9 ziGvfXh;-8Q9U$Qn`#tOrO#e2L5&jfX@vGH@)<$|T^-r%S;d8`a7_XSGJaT^p4eSCu z-+M#;R@3kWLJ2~hL_~YTc?J_0+yfJsg$o3`Mqi9R_+V>%xj<@P!LK&?VNx5I1vjaw zBF~gy=cWE9Hm{DY{#NBS#06Km1%2cm0;l%cY_N)Pgkri%N4iwJN6bb?7^Cqte%RCa zA5UZS^bx`I`%uUr&;!@yZP~r&zvV&5K3-a@dQ;qnz7=*yGN-Rc9Tnt)9LIzw65{ytC YEI~jqBZ(+6pehu7QeZt+EL=c&0PLa^;s5{u literal 0 HcmV?d00001 diff --git a/examples/kotlin/echo/src/main/kotlin/ftl/echo/Echo.kt b/examples/kotlin/echo/src/main/kotlin/ftl/echo/Echo.kt index 3bebf67f3d..ecf114f4a9 100644 --- a/examples/kotlin/echo/src/main/kotlin/ftl/echo/Echo.kt +++ b/examples/kotlin/echo/src/main/kotlin/ftl/echo/Echo.kt @@ -1,18 +1,15 @@ package ftl.echo -import ftl.builtin.Empty -import ftl.time.time -import xyz.block.ftl.Context +import ftl.time.TimeClient import xyz.block.ftl.Export - -class InvalidInput(val field: String) : Exception() +import xyz.block.ftl.Verb data class EchoRequest(val name: String?) data class EchoResponse(val message: String) -@Throws(InvalidInput::class) @Export -fun echo(context: Context, req: EchoRequest): EchoResponse { - val response = context.call(::time, Empty()) +@Verb +fun echo(req: EchoRequest, time: TimeClient): EchoResponse { + val response = time.call() return EchoResponse(message = "Hello, ${req.name ?: "anonymous"}! The time is ${response.time}.") } diff --git a/examples/kotlin/time/ftl.toml b/examples/kotlin/time/ftl.toml index 48033f28f8..e89ed11377 100644 --- a/examples/kotlin/time/ftl.toml +++ b/examples/kotlin/time/ftl.toml @@ -1,2 +1,2 @@ module = "time" -language = "kotlin" +language = "java" diff --git a/examples/kotlin/time/pom.xml b/examples/kotlin/time/pom.xml index 86748eceec..92190cd367 100644 --- a/examples/kotlin/time/pom.xml +++ b/examples/kotlin/time/pom.xml @@ -1,185 +1,182 @@ - + 4.0.0 - - ftl + xyz.block.ftl.examples time - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT 1.0-SNAPSHOT - 1.8 - 1.9.22 - true - ${java.version} - ${java.version} + 3.13.0 + 2.0.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.12.3 + true + 3.2.5 + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} + xyz.block + ftl-java-runtime + 1.0.0-SNAPSHOT - xyz.block - ftl-runtime - ${ftl.version} + io.quarkus + quarkus-kotlin - org.postgresql - postgresql - 42.7.2 + io.quarkus + quarkus-jackson + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-junit5 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + io.rest-assured + kotlin-extensions + test - - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - compile - - compile - - - - ${project.basedir}/src/main/kotlin - - - - - test-compile - - test-compile - - - - ${project.basedir}/src/test/kotlin - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.6.1 - - - - copy-dependencies - compile - - copy-dependencies - - - ${project.build.directory}/dependency - runtime - - - - - build-classpath - compile - - build-classpath - - - ${project.build.directory}/classpath.txt - dependency - - - - build-classpath-property - compile - - build-classpath - - - generated.classpath - ${project.build.directory}/dependency - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/ftl - - - - - - - com.github.ozsie - detekt-maven-plugin - 1.23.5 - - true - ${generated.classpath} - ${java.version} - ${java.home} - ${project.build.directory}/detekt.yml - - - ${project.build.directory}/dependency/ftl-runtime-${ftl.version}.jar - - - ${project.basedir}/src/main/kotlin,${project.build.directory}/generated-sources - - - - compile - - check-with-type-resolution - - - - - - xyz.block - ftl-runtime - ${ftl.version} - - - - - + src/main/kotlin + src/test/kotlin - kotlin-maven-plugin - org.jetbrains.kotlin + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + native-image-agent + + + - org.apache.maven.plugins - maven-dependency-plugin + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + - - org.codehaus.mojo - build-helper-maven-plugin + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + - - com.github.ozsie - detekt-maven-plugin + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + + compile + + + + test-compile + + test-compile + + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + true + 17 + + all-open + + + + + + + + - \ No newline at end of file + + + + native + + + native + + + + false + true + + + + diff --git a/examples/kotlin/time/src/main/kotlin/ftl/time/Time.kt b/examples/kotlin/time/src/main/kotlin/ftl/time/Time.kt index 7158bc5a38..c6dd7f271c 100644 --- a/examples/kotlin/time/src/main/kotlin/ftl/time/Time.kt +++ b/examples/kotlin/time/src/main/kotlin/ftl/time/Time.kt @@ -1,13 +1,13 @@ package ftl.time -import ftl.builtin.Empty -import xyz.block.ftl.Context import xyz.block.ftl.Export +import xyz.block.ftl.Verb import java.time.OffsetDateTime data class TimeResponse(val time: OffsetDateTime) +@Verb @Export -fun time(context: Context, req: Empty): TimeResponse { +fun time(): TimeResponse { return TimeResponse(time = OffsetDateTime.now()) } diff --git a/ftl-project.toml b/ftl-project.toml index f196dc2f02..62f6c086db 100644 --- a/ftl-project.toml +++ b/ftl-project.toml @@ -1,9 +1,12 @@ name = "ftl" module-dirs = ["examples/go"] ftl-min-version = "" +hermit = false +no-git = false [global] [global.configuration] + CUSTOMER_TOKEN_TBD = "inline://InNvbWVDb25maWci" key = "inline://InZhbHVlIg" [modules] diff --git a/go-runtime/compile/build.go b/go-runtime/compile/build.go index f0d1e60382..638a89b4f5 100644 --- a/go-runtime/compile/build.go +++ b/go-runtime/compile/build.go @@ -267,7 +267,7 @@ func CleanStubs(ctx context.Context, projectRoot string) error { // GenerateStubsForModules generates stubs for all modules in the schema. func GenerateStubsForModules(ctx context.Context, projectRoot string, moduleConfigs []moduleconfig.ModuleConfig, sch *schema.Schema) error { logger := log.FromContext(ctx) - logger.Debugf("Generating module stubs") + logger.Debugf("Generating go module stubs") sharedFtlDir := filepath.Join(projectRoot, buildDirName) @@ -275,6 +275,15 @@ func GenerateStubsForModules(ctx context.Context, projectRoot string, moduleConf if ftl.IsRelease(ftl.Version) { ftlVersion = ftl.Version } + hasGo := false + for _, mc := range moduleConfigs { + if mc.Language == "go" && mc.Module != "builtin" { + hasGo = true + } + } + if !hasGo { + return nil + } for _, module := range sch.Modules { var moduleConfig *moduleconfig.ModuleConfig @@ -292,12 +301,18 @@ func GenerateStubsForModules(ctx context.Context, projectRoot string, moduleConf // If there's no module config, use the go.mod file for the first config we find. if moduleConfig == nil { - if len(moduleConfigs) > 0 { - _, goModVersion, err = updateGoModule(filepath.Join(moduleConfigs[0].Dir, "go.mod")) + for _, mod := range moduleConfigs { + if mod.Language != "go" { + continue + } + goModPath := filepath.Join(mod.Dir, "go.mod") + _, goModVersion, err = updateGoModule(goModPath) if err != nil { - return err + logger.Debugf("could not read go.mod %s", goModPath) + continue } - } else { + } + if goModVersion == "" { // The best we can do here if we don't have a module to read from is to use the current Go version. goModVersion = runtime.Version()[2:] } diff --git a/go-runtime/schema/common/directive.go b/go-runtime/schema/common/directive.go index 64db1e164d..ad5c37d92f 100644 --- a/go-runtime/schema/common/directive.go +++ b/go-runtime/schema/common/directive.go @@ -303,7 +303,7 @@ func (d *DirectiveExport) IsExported() bool { type DirectiveTypeMap struct { Pos token.Pos - Runtime string `parser:"'typemap' @('go' | 'kotlin')"` + Runtime string `parser:"'typemap' @('go' | 'kotlin' | 'java')"` NativeName string `parser:"@String"` } diff --git a/java-runtime/.gitignore b/java-runtime/.gitignore new file mode 100644 index 0000000000..08b1802abf --- /dev/null +++ b/java-runtime/.gitignore @@ -0,0 +1,6 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build +generated \ No newline at end of file diff --git a/java-runtime/README.md b/java-runtime/README.md new file mode 100644 index 0000000000..ffe6385512 --- /dev/null +++ b/java-runtime/README.md @@ -0,0 +1,22 @@ +# FTL Java Runtime + +This contains the code for the FTL Java runtime environment. + +## Tips + +### Debugging Maven commands with IntelliJ + +The Java runtime is built and packaged using Maven. If you would like to debug Maven commands using Intellij: + +1. Click `Run->Edit Configurations...` to bring up the run configurations window. + +2. Hit `+` to add a new configuration and select `Remove JVM Debug`. Provide the following configurations and save: +- `Debugger Mode`: `Attach to remote JVM` +- `Host`: `localhost` +- `Port`: `8000` +- `Command line arguments for remote JVM`: `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000` + +3. Run any `mvn` command, substituting `mvnDebug` in place of `mvn` (e.g. `mvnDebug compile`). This command should hang in the terminal, awaiting your remote debugger invocation. +4. Select the newly created debugger from the `Run / Debug Configurations` drop-down in the top right of your IntelliJ +window. With the debugger selected, hit the debug icon to run it. From here the `mvn` command will +execute, stopping at any breakpoints specified. \ No newline at end of file diff --git a/java-runtime/ftl-runtime/deployment/pom.xml b/java-runtime/ftl-runtime/deployment/pom.xml new file mode 100644 index 0000000000..db056f496e --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + + xyz.block + ftl-java-runtime-parent + 1.0.0-SNAPSHOT + + ftl-java-runtime-deployment + Ftl Java Runtime - Deployment + + + + io.quarkus + quarkus-arc-deployment + + + io.quarkus + quarkus-grpc-deployment + + + io.quarkus + quarkus-rest-jackson-deployment + + + + com.squareup + javapoet + + + + xyz.block + ftl-java-runtime + ${project.version} + + + io.quarkus + quarkus-junit5-internal + test + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java new file mode 100644 index 0000000000..4e3c4f7b59 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java @@ -0,0 +1,349 @@ +package xyz.block.ftl.deployment; + +import java.io.IOException; +import java.lang.annotation.Retention; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Stream; + +import javax.lang.model.element.Modifier; + +import org.eclipse.microprofile.config.Config; +import org.jboss.logging.Logger; +import org.jetbrains.annotations.NotNull; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ArrayTypeName; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import com.squareup.javapoet.TypeVariableName; +import com.squareup.javapoet.WildcardTypeName; + +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.prebuild.CodeGenException; +import io.quarkus.deployment.CodeGenContext; +import io.quarkus.deployment.CodeGenProvider; +import xyz.block.ftl.GeneratedRef; +import xyz.block.ftl.Subscription; +import xyz.block.ftl.VerbClient; +import xyz.block.ftl.VerbClientDefinition; +import xyz.block.ftl.VerbClientEmpty; +import xyz.block.ftl.VerbClientSink; +import xyz.block.ftl.VerbClientSource; +import xyz.block.ftl.v1.schema.Module; +import xyz.block.ftl.v1.schema.Type; + +public class FTLCodeGenerator implements CodeGenProvider { + + private static final Logger log = Logger.getLogger(FTLCodeGenerator.class); + + public static final String CLIENT = "Client"; + public static final String PACKAGE_PREFIX = "ftl."; + String moduleName; + + @Override + public void init(ApplicationModel model, Map properties) { + CodeGenProvider.super.init(model, properties); + moduleName = model.getAppArtifact().getArtifactId(); + } + + @Override + public String providerId() { + return "ftl-clients"; + } + + @Override + public String inputDirectory() { + return "ftl-module-schema"; + } + + @Override + public boolean trigger(CodeGenContext context) throws CodeGenException { + if (!Files.isDirectory(context.inputDir())) { + return false; + } + + List modules = new ArrayList<>(); + + Map typeAliasMap = new HashMap<>(); + + try (Stream pathStream = Files.list(context.inputDir())) { + for (var file : pathStream.toList()) { + String fileName = file.getFileName().toString(); + if (!fileName.endsWith(".pb")) { + continue; + } + var module = Module.parseFrom(Files.readAllBytes(file)); + for (var decl : module.getDeclsList()) { + if (decl.hasTypeAlias()) { + var data = decl.getTypeAlias(); + typeAliasMap.put(new Key(module.getName(), data.getName()), data.getType()); + } + } + modules.add(module); + } + } catch (IOException e) { + throw new CodeGenException(e); + } + try { + for (var module : modules) { + String packageName = PACKAGE_PREFIX + module.getName(); + for (var decl : module.getDeclsList()) { + if (decl.hasVerb()) { + var verb = decl.getVerb(); + if (!verb.getExport()) { + continue; + } + + TypeSpec.Builder typeBuilder = TypeSpec.interfaceBuilder(className(verb.getName()) + CLIENT) + .addAnnotation(AnnotationSpec.builder(VerbClientDefinition.class) + .addMember("name", "\"" + verb.getName() + "\"") + .addMember("module", "\"" + module.getName() + "\"") + .build()) + .addModifiers(Modifier.PUBLIC); + if (verb.getRequest().hasUnit() && verb.getResponse().hasUnit()) { + typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientEmpty.class))); + } else if (verb.getRequest().hasUnit()) { + typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientSource.class), + toJavaTypeName(verb.getResponse(), typeAliasMap))); + typeBuilder.addMethod(MethodSpec.methodBuilder("call") + .returns(toAnnotatedJavaTypeName(verb.getResponse(), typeAliasMap)) + .addModifiers(Modifier.ABSTRACT).addModifiers(Modifier.PUBLIC).build()); + } else if (verb.getResponse().hasUnit()) { + typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientSink.class), + toJavaTypeName(verb.getRequest(), typeAliasMap))); + typeBuilder.addMethod(MethodSpec.methodBuilder("call").returns(TypeName.VOID) + .addParameter(toAnnotatedJavaTypeName(verb.getRequest(), typeAliasMap), "value") + .addModifiers(Modifier.ABSTRACT).addModifiers(Modifier.PUBLIC).build()); + } else { + typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClient.class), + toJavaTypeName(verb.getRequest(), typeAliasMap), + toJavaTypeName(verb.getResponse(), typeAliasMap))); + typeBuilder.addMethod(MethodSpec.methodBuilder("call") + .returns(toAnnotatedJavaTypeName(verb.getResponse(), typeAliasMap)) + .addParameter(toAnnotatedJavaTypeName(verb.getRequest(), typeAliasMap), "value") + .addModifiers(Modifier.ABSTRACT).addModifiers(Modifier.PUBLIC).build()); + } + + TypeSpec helloWorld = typeBuilder + .build(); + + JavaFile javaFile = JavaFile.builder(packageName, helloWorld) + .build(); + + javaFile.writeTo(context.outDir()); + + } else if (decl.hasData()) { + var data = decl.getData(); + if (!data.getExport()) { + continue; + } + String thisType = className(data.getName()); + TypeSpec.Builder dataBuilder = TypeSpec.classBuilder(thisType) + .addAnnotation( + AnnotationSpec.builder(GeneratedRef.class) + .addMember("name", "\"" + data.getName() + "\"") + .addMember("module", "\"" + module.getName() + "\"").build()) + .addModifiers(Modifier.PUBLIC); + MethodSpec.Builder allConstructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC); + + dataBuilder.addMethod(allConstructor.build()); + for (var param : data.getTypeParametersList()) { + dataBuilder.addTypeVariable(TypeVariableName.get(param.getName())); + } + Map sortedFields = new TreeMap<>(); + + for (var i : data.getFieldsList()) { + TypeName dataType = toAnnotatedJavaTypeName(i.getType(), typeAliasMap); + String name = i.getName(); + var fieldName = toJavaName(name); + dataBuilder.addField(dataType, fieldName, Modifier.PRIVATE); + sortedFields.put(fieldName, () -> { + allConstructor.addParameter(dataType, fieldName); + allConstructor.addCode("this.$L = $L;\n", fieldName, fieldName); + }); + String methodName = Character.toUpperCase(name.charAt(0)) + name.substring(1); + dataBuilder.addMethod(MethodSpec.methodBuilder("set" + methodName) + .addModifiers(Modifier.PUBLIC) + .addParameter(dataType, fieldName) + .returns(ClassName.get(packageName, thisType)) + .addCode("this.$L = $L;\n", fieldName, fieldName) + .addCode("return this;") + .build()); + if (i.getType().hasBool()) { + dataBuilder.addMethod(MethodSpec.methodBuilder("is" + methodName) + .addModifiers(Modifier.PUBLIC) + .returns(dataType) + .addCode("return $L;", fieldName) + .build()); + } else { + dataBuilder.addMethod(MethodSpec.methodBuilder("get" + methodName) + .addModifiers(Modifier.PUBLIC) + .returns(dataType) + .addCode("return $L;", fieldName) + .build()); + } + } + if (!sortedFields.isEmpty()) { + + for (var v : sortedFields.values()) { + v.run(); + } + dataBuilder.addMethod(allConstructor.build()); + + } + JavaFile javaFile = JavaFile.builder(packageName, dataBuilder.build()) + .build(); + + javaFile.writeTo(context.outDir()); + + } else if (decl.hasEnum()) { + var data = decl.getEnum(); + if (!data.getExport()) { + continue; + } + String thisType = className(data.getName()); + TypeSpec.Builder dataBuilder = TypeSpec.enumBuilder(thisType) + .addAnnotation( + AnnotationSpec.builder(GeneratedRef.class) + .addMember("name", "\"" + data.getName() + "\"") + .addMember("module", "\"" + module.getName() + "\"").build()) + .addModifiers(Modifier.PUBLIC); + + for (var i : data.getVariantsList()) { + dataBuilder.addEnumConstant(i.getName()); + } + + JavaFile javaFile = JavaFile.builder(packageName, dataBuilder.build()) + .build(); + + javaFile.writeTo(context.outDir()); + + } else if (decl.hasTopic()) { + var data = decl.getTopic(); + if (!data.getExport()) { + continue; + } + String thisType = className(data.getName() + "Subscription"); + + TypeSpec.Builder dataBuilder = TypeSpec.annotationBuilder(thisType) + .addModifiers(Modifier.PUBLIC); + if (data.getEvent().hasRef()) { + dataBuilder.addJavadoc("Subscription to the topic of type {@link $L}", + data.getEvent().getRef().getName()); + } + dataBuilder.addAnnotation(AnnotationSpec.builder(Retention.class) + .addMember("value", "java.lang.annotation.RetentionPolicy.RUNTIME").build()); + dataBuilder.addAnnotation(AnnotationSpec.builder(Subscription.class) + .addMember("topic", "\"" + data.getName() + "\"") + .addMember("module", "\"" + module.getName() + "\"") + .addMember("name", "\"" + data.getName() + "Subscription\"") + .build()); + + JavaFile javaFile = JavaFile.builder(packageName, dataBuilder.build()) + .build(); + + javaFile.writeTo(context.outDir()); + + } + } + } + + } catch (Exception e) { + throw new CodeGenException(e); + } + return true; + } + + private String toJavaName(String name) { + if (JAVA_KEYWORDS.contains(name)) { + return name + "_"; + } + return name; + } + + private TypeName toAnnotatedJavaTypeName(Type type, Map typeAliasMap) { + var results = toJavaTypeName(type, typeAliasMap); + if (type.hasRef() || type.hasArray() || type.hasBytes() || type.hasString() || type.hasMap() || type.hasTime()) { + return results.annotated(AnnotationSpec.builder(NotNull.class).build()); + } + return results; + } + + private TypeName toJavaTypeName(Type type, Map typeAliasMap) { + if (type.hasArray()) { + return ParameterizedTypeName.get(ClassName.get(List.class), + toJavaTypeName(type.getArray().getElement(), typeAliasMap)); + } else if (type.hasString()) { + return ClassName.get(String.class); + } else if (type.hasOptional()) { + return toJavaTypeName(type.getOptional().getType(), typeAliasMap); + } else if (type.hasRef()) { + if (type.getRef().getModule().isEmpty()) { + return TypeVariableName.get(type.getRef().getName()); + } + + Key key = new Key(type.getRef().getModule(), type.getRef().getName()); + if (typeAliasMap.containsKey(key)) { + return toJavaTypeName(typeAliasMap.get(key), typeAliasMap); + } + var params = type.getRef().getTypeParametersList(); + ClassName className = ClassName.get(PACKAGE_PREFIX + type.getRef().getModule(), type.getRef().getName()); + if (params.isEmpty()) { + return className; + } + List javaTypes = params.stream() + .map(s -> s.hasUnit() ? WildcardTypeName.subtypeOf(Object.class) : toJavaTypeName(s, typeAliasMap)) + .toList(); + return ParameterizedTypeName.get(className, javaTypes.toArray(new TypeName[javaTypes.size()])); + } else if (type.hasMap()) { + return ParameterizedTypeName.get(ClassName.get(Map.class), toJavaTypeName(type.getMap().getKey(), typeAliasMap), + toJavaTypeName(type.getMap().getValue(), typeAliasMap)); + } else if (type.hasTime()) { + return ClassName.get(Instant.class); + } else if (type.hasInt()) { + return TypeName.LONG; + } else if (type.hasUnit()) { + return TypeName.VOID; + } else if (type.hasBool()) { + return TypeName.BOOLEAN; + } else if (type.hasFloat()) { + return TypeName.DOUBLE; + } else if (type.hasBytes()) { + return ArrayTypeName.of(TypeName.BYTE); + } else if (type.hasAny()) { + return TypeName.OBJECT; + } + + throw new RuntimeException("Cannot generate Java type name: " + type); + } + + @Override + public boolean shouldRun(Path sourceDir, Config config) { + return true; + } + + record Key(String module, String name) { + } + + static String className(String in) { + return Character.toUpperCase(in.charAt(0)) + in.substring(1); + } + + private static final Set JAVA_KEYWORDS = Set.of("abstract", "continue", "for", "new", "switch", "assert", + "default", "goto", "package", "synchronized", "boolean", "do", "if", "private", "this", "break", "double", + "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", + "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", + "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while"); +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java new file mode 100644 index 0000000000..529d4ed36e --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java @@ -0,0 +1,696 @@ +package xyz.block.ftl.deployment; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.ClassType; +import org.jboss.jandex.DotName; +import org.jboss.jandex.MethodInfo; +import org.jboss.jandex.VoidType; +import org.jboss.logging.Logger; +import org.jboss.resteasy.reactive.common.model.MethodParameter; +import org.jboss.resteasy.reactive.common.model.ParameterType; +import org.jboss.resteasy.reactive.server.core.parameters.ParameterExtractor; +import org.jboss.resteasy.reactive.server.mapping.URITemplate; +import org.jboss.resteasy.reactive.server.processor.scanning.MethodScanner; +import org.jetbrains.annotations.NotNull; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.processor.DotNames; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.ApplicationInfoBuildItem; +import io.quarkus.deployment.builditem.ApplicationStartBuildItem; +import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.LaunchModeBuildItem; +import io.quarkus.deployment.builditem.ShutdownContextBuildItem; +import io.quarkus.deployment.builditem.SystemPropertyBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; +import io.quarkus.grpc.deployment.BindableServiceBuildItem; +import io.quarkus.netty.runtime.virtual.VirtualServerChannel; +import io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveResourceMethodEntriesBuildItem; +import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem; +import io.quarkus.vertx.core.deployment.CoreVertxBuildItem; +import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; +import io.quarkus.vertx.http.deployment.RequireVirtualHttpBuildItem; +import io.quarkus.vertx.http.deployment.WebsocketSubProtocolsBuildItem; +import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; +import io.quarkus.vertx.http.runtime.VertxHttpRecorder; +import xyz.block.ftl.Config; +import xyz.block.ftl.Cron; +import xyz.block.ftl.Export; +import xyz.block.ftl.GeneratedRef; +import xyz.block.ftl.Retry; +import xyz.block.ftl.Secret; +import xyz.block.ftl.Subscription; +import xyz.block.ftl.Verb; +import xyz.block.ftl.VerbName; +import xyz.block.ftl.runtime.FTLController; +import xyz.block.ftl.runtime.FTLHttpHandler; +import xyz.block.ftl.runtime.FTLRecorder; +import xyz.block.ftl.runtime.TopicHelper; +import xyz.block.ftl.runtime.VerbClientHelper; +import xyz.block.ftl.runtime.VerbHandler; +import xyz.block.ftl.runtime.VerbRegistry; +import xyz.block.ftl.runtime.builtin.HttpRequest; +import xyz.block.ftl.runtime.builtin.HttpResponse; +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.schema.Array; +import xyz.block.ftl.v1.schema.Bool; +import xyz.block.ftl.v1.schema.Data; +import xyz.block.ftl.v1.schema.Decl; +import xyz.block.ftl.v1.schema.Field; +import xyz.block.ftl.v1.schema.Float; +import xyz.block.ftl.v1.schema.IngressPathComponent; +import xyz.block.ftl.v1.schema.IngressPathLiteral; +import xyz.block.ftl.v1.schema.IngressPathParameter; +import xyz.block.ftl.v1.schema.Int; +import xyz.block.ftl.v1.schema.Metadata; +import xyz.block.ftl.v1.schema.MetadataCalls; +import xyz.block.ftl.v1.schema.MetadataCronJob; +import xyz.block.ftl.v1.schema.MetadataIngress; +import xyz.block.ftl.v1.schema.MetadataRetry; +import xyz.block.ftl.v1.schema.MetadataSubscriber; +import xyz.block.ftl.v1.schema.Module; +import xyz.block.ftl.v1.schema.Optional; +import xyz.block.ftl.v1.schema.Ref; +import xyz.block.ftl.v1.schema.Time; +import xyz.block.ftl.v1.schema.Type; +import xyz.block.ftl.v1.schema.Unit; + +class FtlProcessor { + + private static final Logger log = Logger.getLogger(FtlProcessor.class); + + private static final String SCHEMA_OUT = "schema.pb"; + private static final String FEATURE = "ftl-java-runtime"; + public static final DotName EXPORT = DotName.createSimple(Export.class); + public static final DotName VERB = DotName.createSimple(Verb.class); + public static final DotName CRON = DotName.createSimple(Cron.class); + public static final DotName SUBSCRIPTION = DotName.createSimple(Subscription.class); + public static final String BUILTIN = "builtin"; + public static final DotName CONSUMER = DotName.createSimple(Consumer.class); + public static final DotName SECRET = DotName.createSimple(Secret.class); + public static final DotName CONFIG = DotName.createSimple(Config.class); + public static final DotName OFFSET_DATE_TIME = DotName.createSimple(OffsetDateTime.class.getName()); + public static final DotName GENERATED_REF = DotName.createSimple(GeneratedRef.class); + + @BuildStep + ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem) { + return new ModuleNameBuildItem(applicationInfoBuildItem.getName()); + + } + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + + @BuildStep + BindableServiceBuildItem verbService() { + var ret = new BindableServiceBuildItem(DotName.createSimple(VerbHandler.class)); + ret.registerBlockingMethod("call"); + ret.registerBlockingMethod("publishEvent"); + ret.registerBlockingMethod("sendFSMEvent"); + ret.registerBlockingMethod("acquireLease"); + ret.registerBlockingMethod("getModuleContext"); + ret.registerBlockingMethod("ping"); + return ret; + } + + @BuildStep + AdditionalBeanBuildItem beans() { + return AdditionalBeanBuildItem.builder() + .addBeanClasses(VerbHandler.class, VerbRegistry.class, FTLHttpHandler.class, FTLController.class, + TopicHelper.class, VerbClientHelper.class) + .setUnremovable().build(); + } + + @BuildStep + AdditionalBeanBuildItem verbBeans(CombinedIndexBuildItem index) { + + var beans = AdditionalBeanBuildItem.builder().setUnremovable(); + for (var verb : index.getIndex().getAnnotations(VERB)) { + beans.addBeanClasses(verb.target().asMethod().declaringClass().name().toString()); + } + return beans.build(); + } + + @BuildStep + public SystemPropertyBuildItem moduleNameConfig(ApplicationInfoBuildItem applicationInfoBuildItem) { + return new SystemPropertyBuildItem("ftl.module.name", applicationInfoBuildItem.getName()); + } + + @BuildStep + @Record(ExecutionTime.RUNTIME_INIT) + public MethodScannerBuildItem methodScanners(TopicsBuildItem topics, + VerbClientBuildItem verbClients, FTLRecorder recorder) { + return new MethodScannerBuildItem(new MethodScanner() { + @Override + public ParameterExtractor handleCustomParameter(org.jboss.jandex.Type type, + Map annotations, boolean field, Map methodContext) { + try { + + if (annotations.containsKey(SECRET)) { + Class paramType = loadClass(type); + String name = annotations.get(SECRET).value().asString(); + return new VerbRegistry.SecretSupplier(name, paramType); + } else if (annotations.containsKey(CONFIG)) { + Class paramType = loadClass(type); + String name = annotations.get(CONFIG).value().asString(); + return new VerbRegistry.ConfigSupplier(name, paramType); + } else if (topics.getTopics().containsKey(type.name())) { + var topic = topics.getTopics().get(type.name()); + Class paramType = loadClass(type); + return recorder.topicParamExtractor(topic.generatedProducer()); + } else if (verbClients.getVerbClients().containsKey(type.name())) { + var client = verbClients.getVerbClients().get(type.name()); + Class paramType = loadClass(type); + return recorder.verbParamExtractor(client.generatedClient()); + } + return null; + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + }); + } + + @BuildStep + @Record(ExecutionTime.RUNTIME_INIT) + public void registerVerbs(CombinedIndexBuildItem index, + FTLRecorder recorder, + OutputTargetBuildItem outputTargetBuildItem, + ResteasyReactiveResourceMethodEntriesBuildItem restEndpoints, + TopicsBuildItem topics, + VerbClientBuildItem verbClients, + ModuleNameBuildItem moduleNameBuildItem, + SubscriptionMetaAnnotationsBuildItem subscriptionMetaAnnotationsBuildItem) throws Exception { + String moduleName = moduleNameBuildItem.getModuleName(); + Module.Builder moduleBuilder = Module.newBuilder() + .setName(moduleName) + .setBuiltin(false); + Map dataElements = new HashMap<>(); + ExtractionContext extractionContext = new ExtractionContext(moduleName, index, recorder, moduleBuilder, dataElements, + new HashSet<>(), new HashSet<>(), topics.getTopics(), verbClients.getVerbClients()); + var beans = AdditionalBeanBuildItem.builder().setUnremovable(); + + //register all the topics we are defining in the module definition + + for (var topic : topics.getTopics().values()) { + extractionContext.moduleBuilder.addDecls(Decl.newBuilder().setTopic(xyz.block.ftl.v1.schema.Topic.newBuilder() + .setExport(topic.exported()) + .setName(topic.topicName()) + .setEvent(buildType(extractionContext, topic.eventType())).build())); + } + + handleVerbAnnotations(index, beans, extractionContext); + handleCronAnnotations(index, beans, extractionContext); + handleSubscriptionAnnotations(index, subscriptionMetaAnnotationsBuildItem, moduleName, moduleBuilder, extractionContext, + beans); + + //TODO: make this composable so it is not just one big method, build items should contribute to the schema + for (var endpoint : restEndpoints.getEntries()) { + //TODO: naming + var verbName = methodToName(endpoint.getMethodInfo()); + recorder.registerHttpIngress(moduleName, verbName); + + //TODO: handle type parameters properly + org.jboss.jandex.Type bodyParamType = VoidType.VOID; + MethodParameter[] parameters = endpoint.getResourceMethod().getParameters(); + for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { + var param = parameters[i]; + if (param.parameterType.equals(ParameterType.BODY)) { + bodyParamType = endpoint.getMethodInfo().parameterType(i); + break; + } + } + + StringBuilder pathBuilder = new StringBuilder(); + if (endpoint.getBasicResourceClassInfo().getPath() != null) { + pathBuilder.append(endpoint.getBasicResourceClassInfo().getPath()); + } + if (endpoint.getResourceMethod().getPath() != null && !endpoint.getResourceMethod().getPath().isEmpty()) { + if (pathBuilder.charAt(pathBuilder.length() - 1) != '/' + && !endpoint.getResourceMethod().getPath().startsWith("/")) { + pathBuilder.append('/'); + } + pathBuilder.append(endpoint.getResourceMethod().getPath()); + } + String path = pathBuilder.toString(); + URITemplate template = new URITemplate(path, false); + List pathComponents = new ArrayList<>(); + for (var i : template.components) { + if (i.type == URITemplate.Type.CUSTOM_REGEX) { + throw new RuntimeException( + "Invalid path " + path + " on HTTP endpoint: " + endpoint.getActualClassInfo().name() + "." + + methodToName(endpoint.getMethodInfo()) + + " FTL does not support custom regular expressions"); + } else if (i.type == URITemplate.Type.LITERAL) { + if (i.literalText.equals("/")) { + continue; + } + pathComponents.add(IngressPathComponent.newBuilder() + .setIngressPathLiteral(IngressPathLiteral.newBuilder().setText(i.literalText.replace("/", ""))) + .build()); + } else { + pathComponents.add(IngressPathComponent.newBuilder() + .setIngressPathParameter(IngressPathParameter.newBuilder().setName(i.name.replace("/", ""))) + .build()); + } + } + + //TODO: process path properly + MetadataIngress.Builder ingressBuilder = MetadataIngress.newBuilder() + .setMethod(endpoint.getResourceMethod().getHttpMethod()); + for (var i : pathComponents) { + ingressBuilder.addPath(i); + } + Metadata ingressMetadata = Metadata.newBuilder() + .setIngress(ingressBuilder + .build()) + .build(); + Type requestTypeParam = buildType(extractionContext, bodyParamType); + Type responseTypeParam = buildType(extractionContext, endpoint.getMethodInfo().returnType()); + moduleBuilder + .addDecls(Decl.newBuilder().setVerb(xyz.block.ftl.v1.schema.Verb.newBuilder() + .addMetadata(ingressMetadata) + .setName(verbName) + .setExport(true) + .setRequest(Type.newBuilder() + .setRef(Ref.newBuilder().setModule(BUILTIN).setName(HttpRequest.class.getSimpleName()) + .addTypeParameters(requestTypeParam)) + .build()) + .setResponse(Type.newBuilder() + .setRef(Ref.newBuilder().setModule(BUILTIN).setName(HttpResponse.class.getSimpleName()) + .addTypeParameters(responseTypeParam) + .addTypeParameters(Type.newBuilder().setUnit(Unit.newBuilder()))) + .build())) + .build()); + } + + Path output = outputTargetBuildItem.getOutputDirectory().resolve(SCHEMA_OUT); + try (var out = Files.newOutputStream(output)) { + moduleBuilder.build().writeTo(out); + } + + output = outputTargetBuildItem.getOutputDirectory().resolve("main"); + try (var out = Files.newOutputStream(output)) { + out.write(""" + #!/bin/bash + exec java -jar quarkus-app/quarkus-run.jar""".getBytes(StandardCharsets.UTF_8)); + } + var perms = Files.getPosixFilePermissions(output); + EnumSet newPerms = EnumSet.copyOf(perms); + newPerms.add(PosixFilePermission.GROUP_EXECUTE); + newPerms.add(PosixFilePermission.OWNER_EXECUTE); + Files.setPosixFilePermissions(output, newPerms); + } + + private void handleVerbAnnotations(CombinedIndexBuildItem index, AdditionalBeanBuildItem.Builder beans, + ExtractionContext extractionContext) { + for (var verb : index.getIndex().getAnnotations(VERB)) { + boolean exported = verb.target().hasAnnotation(EXPORT); + var method = verb.target().asMethod(); + String className = method.declaringClass().name().toString(); + beans.addBeanClass(className); + + handleVerbMethod(extractionContext, method, className, exported, BodyType.ALLOWED, null); + } + } + + private void handleSubscriptionAnnotations(CombinedIndexBuildItem index, + SubscriptionMetaAnnotationsBuildItem subscriptionMetaAnnotationsBuildItem, String moduleName, + Module.Builder moduleBuilder, ExtractionContext extractionContext, AdditionalBeanBuildItem.Builder beans) { + for (var subscription : index.getIndex().getAnnotations(SUBSCRIPTION)) { + var info = SubscriptionMetaAnnotationsBuildItem.fromJandex(subscription, moduleName); + if (subscription.target().kind() != AnnotationTarget.Kind.METHOD) { + continue; + } + var method = subscription.target().asMethod(); + String className = method.declaringClass().name().toString(); + generateSubscription(moduleBuilder, extractionContext, beans, method, className, info); + } + for (var metaSub : subscriptionMetaAnnotationsBuildItem.getAnnotations().entrySet()) { + for (var subscription : index.getIndex().getAnnotations(metaSub.getKey())) { + if (subscription.target().kind() != AnnotationTarget.Kind.METHOD) { + log.warnf("Subscription annotation on non-method target: %s", subscription.target()); + continue; + } + var method = subscription.target().asMethod(); + generateSubscription(moduleBuilder, extractionContext, beans, method, + method.declaringClass().name().toString(), + metaSub.getValue()); + } + + } + } + + private void handleCronAnnotations(CombinedIndexBuildItem index, AdditionalBeanBuildItem.Builder beans, + ExtractionContext extractionContext) { + for (var cron : index.getIndex().getAnnotations(CRON)) { + var method = cron.target().asMethod(); + String className = method.declaringClass().name().toString(); + beans.addBeanClass(className); + handleVerbMethod(extractionContext, method, className, false, BodyType.DISALLOWED, (builder -> { + builder.addMetadata(Metadata.newBuilder() + .setCronJob(MetadataCronJob.newBuilder().setCron(cron.value().asString())).build()); + })); + } + } + + private void generateSubscription(Module.Builder moduleBuilder, ExtractionContext extractionContext, + AdditionalBeanBuildItem.Builder beans, MethodInfo method, String className, + SubscriptionMetaAnnotationsBuildItem.SubscriptionAnnotation info) { + beans.addBeanClass(className); + moduleBuilder.addDecls(Decl.newBuilder().setSubscription(xyz.block.ftl.v1.schema.Subscription.newBuilder() + .setName(info.name()).setTopic(Ref.newBuilder().setName(info.topic()).setModule(info.module()).build())) + .build()); + handleVerbMethod(extractionContext, method, className, false, BodyType.REQUIRED, (builder -> { + builder.addMetadata(Metadata.newBuilder().setSubscriber(MetadataSubscriber.newBuilder().setName(info.name()))); + if (method.hasAnnotation(Retry.class)) { + RetryRecord retry = RetryRecord.fromJandex(method.annotation(Retry.class), extractionContext.moduleName); + + MetadataRetry.Builder retryBuilder = MetadataRetry.newBuilder(); + if (!retry.catchVerb().isEmpty()) { + retryBuilder.setCatch(Ref.newBuilder().setModule(retry.catchModule()) + .setName(retry.catchVerb()).build()); + } + retryBuilder.setCount(retry.count()) + .setMaxBackoff(retry.maxBackoff()) + .setMinBackoff(retry.minBackoff()); + builder.addMetadata(Metadata.newBuilder().setRetry(retryBuilder).build()); + } + })); + } + + private void handleVerbMethod(ExtractionContext context, MethodInfo method, String className, + boolean exported, BodyType bodyType, Consumer metadataCallback) { + try { + List> parameterTypes = new ArrayList<>(); + List> paramMappers = new ArrayList<>(); + org.jboss.jandex.Type bodyParamType = null; + xyz.block.ftl.v1.schema.Verb.Builder verbBuilder = xyz.block.ftl.v1.schema.Verb.newBuilder(); + String verbName = methodToName(method); + MetadataCalls.Builder callsMetadata = MetadataCalls.newBuilder(); + for (var param : method.parameters()) { + if (param.hasAnnotation(Secret.class)) { + Class paramType = loadClass(param.type()); + parameterTypes.add(paramType); + String name = param.annotation(Secret.class).value().asString(); + paramMappers.add(new VerbRegistry.SecretSupplier(name, paramType)); + if (!context.knownSecrets.contains(name)) { + context.moduleBuilder.addDecls(Decl.newBuilder().setSecret(xyz.block.ftl.v1.schema.Secret.newBuilder() + .setType(buildType(context, param.type())).setName(name))); + context.knownSecrets.add(name); + } + } else if (param.hasAnnotation(Config.class)) { + Class paramType = loadClass(param.type()); + parameterTypes.add(paramType); + String name = param.annotation(Config.class).value().asString(); + paramMappers.add(new VerbRegistry.ConfigSupplier(name, paramType)); + if (!context.knownConfig.contains(name)) { + context.moduleBuilder.addDecls(Decl.newBuilder().setConfig(xyz.block.ftl.v1.schema.Config.newBuilder() + .setType(buildType(context, param.type())).setName(name))); + context.knownConfig.add(name); + } + } else if (context.knownTopics.containsKey(param.type().name())) { + var topic = context.knownTopics.get(param.type().name()); + Class paramType = loadClass(param.type()); + parameterTypes.add(paramType); + paramMappers.add(context.recorder().topicSupplier(topic.generatedProducer(), verbName)); + } else if (context.verbClients.containsKey(param.type().name())) { + var client = context.verbClients.get(param.type().name()); + Class paramType = loadClass(param.type()); + parameterTypes.add(paramType); + paramMappers.add(context.recorder().verbClientSupplier(client.generatedClient())); + callsMetadata.addCalls(Ref.newBuilder().setName(client.name()).setModule(client.module()).build()); + } else if (bodyType != BodyType.DISALLOWED && bodyParamType == null) { + bodyParamType = param.type(); + Class paramType = loadClass(param.type()); + parameterTypes.add(paramType); + //TODO: map and list types + paramMappers.add(new VerbRegistry.BodySupplier(paramType)); + } else { + throw new RuntimeException("Unknown parameter type " + param.type() + " on FTL method: " + + method.declaringClass().name() + "." + method.name()); + } + } + if (bodyParamType == null) { + if (bodyType == BodyType.REQUIRED) { + throw new RuntimeException("Missing required payload parameter"); + } + bodyParamType = VoidType.VOID; + } + if (callsMetadata.getCallsCount() > 0) { + verbBuilder.addMetadata(Metadata.newBuilder().setCalls(callsMetadata)); + } + + context.recorder.registerVerb(context.moduleName(), verbName, method.name(), parameterTypes, + Class.forName(className, false, Thread.currentThread().getContextClassLoader()), paramMappers); + verbBuilder + .setName(verbName) + .setExport(exported) + .setRequest(buildType(context, bodyParamType)) + .setResponse(buildType(context, method.returnType())); + + if (metadataCallback != null) { + metadataCallback.accept(verbBuilder); + } + context.moduleBuilder + .addDecls(Decl.newBuilder().setVerb(verbBuilder) + .build()); + + } catch (Exception e) { + throw new RuntimeException("Failed to process FTL method " + method.declaringClass().name() + "." + method.name(), + e); + } + } + + private static @NotNull String methodToName(MethodInfo method) { + if (method.hasAnnotation(VerbName.class)) { + return method.annotation(VerbName.class).value().asString(); + } + return method.name(); + } + + private static Class loadClass(org.jboss.jandex.Type param) throws ClassNotFoundException { + if (param.kind() == org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE) { + return Class.forName(param.asParameterizedType().name().toString(), false, + Thread.currentThread().getContextClassLoader()); + } else if (param.kind() == org.jboss.jandex.Type.Kind.CLASS) { + return Class.forName(param.name().toString(), false, Thread.currentThread().getContextClassLoader()); + } else if (param.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE) { + switch (param.asPrimitiveType().primitive()) { + case BOOLEAN: + return Boolean.TYPE; + case BYTE: + return Byte.TYPE; + case SHORT: + return Short.TYPE; + case INT: + return Integer.TYPE; + case LONG: + return Long.TYPE; + case FLOAT: + return java.lang.Float.TYPE; + case DOUBLE: + return java.lang.Double.TYPE; + case CHAR: + return Character.TYPE; + default: + throw new RuntimeException("Unknown primitive type " + param.asPrimitiveType().primitive()); + } + } else { + throw new RuntimeException("Unknown type " + param.kind()); + } + } + + /** + * This is a huge hack that is needed until Quarkus supports both virtual and socket based HTTP + */ + @Record(ExecutionTime.RUNTIME_INIT) + @BuildStep + void openSocket(ApplicationStartBuildItem start, + LaunchModeBuildItem launchMode, + CoreVertxBuildItem vertx, + ShutdownContextBuildItem shutdown, + BuildProducer reflectiveClass, + HttpBuildTimeConfig httpBuildTimeConfig, + java.util.Optional requireVirtual, + EventLoopCountBuildItem eventLoopCount, + List websocketSubProtocols, + Capabilities capabilities, + VertxHttpRecorder recorder) throws IOException { + reflectiveClass + .produce(ReflectiveClassBuildItem.builder(VirtualServerChannel.class) + .build()); + recorder.startServer(vertx.getVertx(), shutdown, + launchMode.getLaunchMode(), true, false, + eventLoopCount.getEventLoopCount(), + websocketSubProtocols.stream().map(bi -> bi.getWebsocketSubProtocols()) + .collect(Collectors.toList()), + launchMode.isAuxiliaryApplication(), !capabilities.isPresent(Capability.VERTX_WEBSOCKETS)); + } + + private Type buildType(ExtractionContext context, org.jboss.jandex.Type type) { + switch (type.kind()) { + case PRIMITIVE -> { + var prim = type.asPrimitiveType(); + switch (prim.primitive()) { + case INT, LONG, BYTE, SHORT -> { + return Type.newBuilder().setInt(Int.newBuilder().build()).build(); + } + case FLOAT, DOUBLE -> { + return Type.newBuilder().setFloat(Float.newBuilder().build()).build(); + } + case BOOLEAN -> { + return Type.newBuilder().setBool(Bool.newBuilder().build()).build(); + } + case CHAR -> { + return Type.newBuilder().setString(xyz.block.ftl.v1.schema.String.newBuilder().build()).build(); + } + default -> throw new RuntimeException("unknown primitive type: " + prim.primitive()); + } + } + case VOID -> { + return Type.newBuilder().setUnit(Unit.newBuilder().build()).build(); + } + case ARRAY -> { + return Type.newBuilder() + .setArray(Array.newBuilder().setElement(buildType(context, type.asArrayType().componentType())).build()) + .build(); + } + case CLASS -> { + var clazz = type.asClassType(); + var info = context.index().getComputingIndex().getClassByName(clazz.name()); + if (info != null && info.hasDeclaredAnnotation(GENERATED_REF)) { + var ref = info.declaredAnnotation(GENERATED_REF); + return Type.newBuilder() + .setRef(Ref.newBuilder().setName(ref.value("name").asString()) + .setModule(ref.value("module").asString())) + .build(); + } + if (clazz.name().equals(DotName.STRING_NAME)) { + return Type.newBuilder().setString(xyz.block.ftl.v1.schema.String.newBuilder().build()).build(); + } + if (clazz.name().equals(OFFSET_DATE_TIME)) { + return Type.newBuilder().setTime(Time.newBuilder().build()).build(); + } + var existing = context.dataElements.get(new TypeKey(clazz.name().toString(), List.of())); + if (existing != null) { + return Type.newBuilder().setRef(existing).build(); + } + Data.Builder data = Data.newBuilder(); + data.setName(clazz.name().local()); + data.setExport(type.hasAnnotation(EXPORT)); + buildDataElement(context, data, clazz.name()); + context.moduleBuilder.addDecls(Decl.newBuilder().setData(data).build()); + Ref ref = Ref.newBuilder().setName(data.getName()).setModule(context.moduleName).build(); + context.dataElements.put(new TypeKey(clazz.name().toString(), List.of()), ref); + return Type.newBuilder().setRef(ref).build(); + } + case PARAMETERIZED_TYPE -> { + var paramType = type.asParameterizedType(); + if (paramType.name().equals(DotName.createSimple(List.class))) { + return Type.newBuilder() + .setArray(Array.newBuilder().setElement(buildType(context, paramType.arguments().get(0)))).build(); + } else if (paramType.name().equals(DotName.createSimple(Map.class))) { + return Type.newBuilder().setMap(xyz.block.ftl.v1.schema.Map.newBuilder() + .setKey(buildType(context, paramType.arguments().get(0))) + .setValue(buildType(context, paramType.arguments().get(0)))) + .build(); + } else if (paramType.name().equals(DotNames.OPTIONAL)) { + return Type.newBuilder() + .setOptional(Optional.newBuilder().setType(buildType(context, paramType.arguments().get(0)))) + .build(); + } else if (paramType.name().equals(DotName.createSimple(HttpRequest.class))) { + return Type.newBuilder() + .setRef(Ref.newBuilder().setModule(BUILTIN).setName(HttpRequest.class.getSimpleName()) + .addTypeParameters(buildType(context, paramType.arguments().get(0)))) + .build(); + } else if (paramType.name().equals(DotName.createSimple(HttpResponse.class))) { + return Type.newBuilder() + .setRef(Ref.newBuilder().setModule(BUILTIN).setName(HttpResponse.class.getSimpleName()) + .addTypeParameters(buildType(context, paramType.arguments().get(0))) + .addTypeParameters(Type.newBuilder().setUnit(Unit.newBuilder().build()))) + .build(); + } else { + ClassInfo classByName = context.index().getComputingIndex().getClassByName(paramType.name()); + var cb = ClassType.builder(classByName.name()); + var main = buildType(context, cb.build()); + var builder = main.toBuilder(); + var refBuilder = builder.getRef().toBuilder(); + + for (var arg : paramType.arguments()) { + refBuilder.addTypeParameters(buildType(context, arg)); + } + builder.setRef(refBuilder); + return builder.build(); + } + } + } + + throw new RuntimeException("NOT YET IMPLEMENTED"); + } + + private void buildDataElement(ExtractionContext context, Data.Builder data, DotName className) { + if (className == null || className.equals(DotName.OBJECT_NAME)) { + return; + } + var clazz = context.index.getComputingIndex().getClassByName(className); + if (clazz == null) { + return; + } + //TODO: handle getters and setters properly, also Jackson annotations etc + for (var field : clazz.fields()) { + if (!Modifier.isStatic(field.flags())) { + data.addFields(Field.newBuilder().setName(field.name()).setType(buildType(context, field.type())).build()); + } + } + buildDataElement(context, data, clazz.superName()); + } + + private record TypeKey(String name, List typeParams) { + + } + + record ExtractionContext(String moduleName, CombinedIndexBuildItem index, FTLRecorder recorder, + Module.Builder moduleBuilder, + Map dataElements, Set knownSecrets, Set knownConfig, + Map knownTopics, + Map verbClients) { + } + + enum BodyType { + DISALLOWED, + ALLOWED, + REQUIRED + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/ModuleNameBuildItem.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/ModuleNameBuildItem.java new file mode 100644 index 0000000000..c47c10bcf5 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/ModuleNameBuildItem.java @@ -0,0 +1,16 @@ +package xyz.block.ftl.deployment; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class ModuleNameBuildItem extends SimpleBuildItem { + + final String moduleName; + + public ModuleNameBuildItem(String moduleName) { + this.moduleName = moduleName; + } + + public String getModuleName() { + return moduleName; + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/RetryRecord.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/RetryRecord.java new file mode 100644 index 0000000000..8cf3621b68 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/RetryRecord.java @@ -0,0 +1,19 @@ +package xyz.block.ftl.deployment; + +import org.jboss.jandex.AnnotationInstance; + +public record RetryRecord(int count, String minBackoff, String maxBackoff, String catchModule, String catchVerb) { + + public static RetryRecord fromJandex(AnnotationInstance nested, String currentModuleName) { + return new RetryRecord( + nested.value("count") != null ? nested.value("count").asInt() : 0, + nested.value("minBackoff") != null ? nested.value("minBackoff").asString() : "", + nested.value("maxBackoff") != null ? nested.value("maxBackoff").asString() : "", + nested.value("catchModule") != null ? nested.value("catchModule").asString() : currentModuleName, + nested.value("catchVerb") != null ? nested.value("catchVerb").asString() : ""); + } + + public boolean isEmpty() { + return count == 0 && minBackoff.isEmpty() && maxBackoff.isEmpty() && catchVerb.isEmpty(); + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/SubscriptionMetaAnnotationsBuildItem.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/SubscriptionMetaAnnotationsBuildItem.java new file mode 100644 index 0000000000..83e2d35cf5 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/SubscriptionMetaAnnotationsBuildItem.java @@ -0,0 +1,35 @@ +package xyz.block.ftl.deployment; + +import java.util.Map; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.DotName; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class SubscriptionMetaAnnotationsBuildItem extends SimpleBuildItem { + + private final Map annotations; + + public SubscriptionMetaAnnotationsBuildItem(Map annotations) { + this.annotations = annotations; + } + + public Map getAnnotations() { + return annotations; + } + + public record SubscriptionAnnotation(String module, String topic, String name) { + } + + public static SubscriptionAnnotation fromJandex(AnnotationInstance subscriptions, String currentModuleName) { + AnnotationValue moduleValue = subscriptions.value("module"); + + return new SubscriptionMetaAnnotationsBuildItem.SubscriptionAnnotation( + moduleValue == null || moduleValue.asString().isEmpty() ? currentModuleName + : moduleValue.asString(), + subscriptions.value("topic").asString(), + subscriptions.value("name").asString()); + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsBuildItem.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsBuildItem.java new file mode 100644 index 0000000000..fcbbd78275 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsBuildItem.java @@ -0,0 +1,26 @@ +package xyz.block.ftl.deployment; + +import java.util.HashMap; +import java.util.Map; + +import org.jboss.jandex.DotName; +import org.jboss.jandex.Type; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class TopicsBuildItem extends SimpleBuildItem { + + final Map topics; + + public TopicsBuildItem(Map topics) { + this.topics = new HashMap<>(topics); + } + + public Map getTopics() { + return topics; + } + + public record DiscoveredTopic(String topicName, String generatedProducer, Type eventType, boolean exported) { + + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsProcessor.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsProcessor.java new file mode 100644 index 0000000000..367393890a --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/TopicsProcessor.java @@ -0,0 +1,97 @@ +package xyz.block.ftl.deployment; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Type; + +import io.quarkus.deployment.GeneratedClassGizmoAdaptor; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.GeneratedClassBuildItem; +import io.quarkus.gizmo.ClassCreator; +import io.quarkus.gizmo.MethodDescriptor; +import xyz.block.ftl.Export; +import xyz.block.ftl.Subscription; +import xyz.block.ftl.Topic; +import xyz.block.ftl.TopicDefinition; +import xyz.block.ftl.runtime.TopicHelper; + +public class TopicsProcessor { + + public static final DotName TOPIC = DotName.createSimple(Topic.class); + + @BuildStep + TopicsBuildItem handleTopics(CombinedIndexBuildItem index, BuildProducer generatedTopicProducer) { + var topicDefinitions = index.getComputingIndex().getAnnotations(TopicDefinition.class); + Map topics = new HashMap<>(); + Set names = new HashSet<>(); + for (var topicDefinition : topicDefinitions) { + var iface = topicDefinition.target().asClass(); + if (!iface.isInterface()) { + throw new RuntimeException( + "@TopicDefinition can only be applied to interfaces " + iface.name() + " is not an interface"); + } + Type paramType = null; + for (var i : iface.interfaceTypes()) { + if (i.name().equals(TOPIC)) { + if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { + paramType = i.asParameterizedType().arguments().get(0); + } + } + + } + if (paramType == null) { + throw new RuntimeException("@TopicDefinition can only be applied to interfaces that directly extend " + TOPIC + + " with a concrete type parameter " + iface.name() + " does not extend this interface"); + } + + String name = topicDefinition.value("name").asString(); + if (names.contains(name)) { + throw new RuntimeException("Multiple topic definitions found for topic " + name); + } + names.add(name); + try (ClassCreator cc = new ClassCreator(new GeneratedClassGizmoAdaptor(generatedTopicProducer, true), + iface.name().toString() + "_fit_topic", null, Object.class.getName(), iface.name().toString())) { + var verb = cc.getFieldCreator("verb", String.class); + var constructor = cc.getConstructorCreator(String.class); + constructor.invokeSpecialMethod(MethodDescriptor.ofMethod(Object.class, "", void.class), + constructor.getThis()); + constructor.writeInstanceField(verb.getFieldDescriptor(), constructor.getThis(), constructor.getMethodParam(0)); + constructor.returnVoid(); + var publish = cc.getMethodCreator("publish", void.class, Object.class); + var helper = publish + .invokeStaticMethod(MethodDescriptor.ofMethod(TopicHelper.class, "instance", TopicHelper.class)); + publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(TopicHelper.class, "publish", void.class, String.class, String.class, + Object.class), + helper, publish.load(name), publish.readInstanceField(verb.getFieldDescriptor(), publish.getThis()), + publish.getMethodParam(0)); + publish.returnVoid(); + topics.put(iface.name(), new TopicsBuildItem.DiscoveredTopic(name, cc.getClassName(), paramType, + iface.hasAnnotation(Export.class))); + } + } + return new TopicsBuildItem(topics); + } + + @BuildStep + SubscriptionMetaAnnotationsBuildItem subscriptionAnnotations(CombinedIndexBuildItem combinedIndexBuildItem, + ModuleNameBuildItem moduleNameBuildItem) { + + Map annotations = new HashMap<>(); + for (var subscriptions : combinedIndexBuildItem.getComputingIndex().getAnnotations(Subscription.class)) { + if (subscriptions.target().kind() != AnnotationTarget.Kind.CLASS) { + continue; + } + annotations.put(subscriptions.target().asClass().name(), + SubscriptionMetaAnnotationsBuildItem.fromJandex(subscriptions, moduleNameBuildItem.getModuleName())); + } + return new SubscriptionMetaAnnotationsBuildItem(annotations); + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientBuildItem.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientBuildItem.java new file mode 100644 index 0000000000..669e005bf5 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientBuildItem.java @@ -0,0 +1,25 @@ +package xyz.block.ftl.deployment; + +import java.util.HashMap; +import java.util.Map; + +import org.jboss.jandex.DotName; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class VerbClientBuildItem extends SimpleBuildItem { + + final Map verbClients; + + public VerbClientBuildItem(Map verbClients) { + this.verbClients = new HashMap<>(verbClients); + } + + public Map getVerbClients() { + return verbClients; + } + + public record DiscoveredClients(String name, String module, String generatedClient) { + + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientsProcessor.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientsProcessor.java new file mode 100644 index 0000000000..7d590a9a0f --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/VerbClientsProcessor.java @@ -0,0 +1,212 @@ +package xyz.block.ftl.deployment; + +import java.util.HashMap; +import java.util.Map; + +import jakarta.inject.Singleton; + +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Type; + +import io.quarkus.arc.deployment.GeneratedBeanBuildItem; +import io.quarkus.arc.deployment.GeneratedBeanGizmoAdaptor; +import io.quarkus.deployment.GeneratedClassGizmoAdaptor; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.GeneratedClassBuildItem; +import io.quarkus.deployment.builditem.LaunchModeBuildItem; +import io.quarkus.gizmo.ClassCreator; +import io.quarkus.gizmo.ClassOutput; +import io.quarkus.gizmo.MethodDescriptor; +import xyz.block.ftl.VerbClient; +import xyz.block.ftl.VerbClientDefinition; +import xyz.block.ftl.VerbClientEmpty; +import xyz.block.ftl.VerbClientSink; +import xyz.block.ftl.VerbClientSource; +import xyz.block.ftl.runtime.VerbClientHelper; + +public class VerbClientsProcessor { + + public static final DotName VERB_CLIENT = DotName.createSimple(VerbClient.class); + public static final DotName VERB_CLIENT_SINK = DotName.createSimple(VerbClientSink.class); + public static final DotName VERB_CLIENT_SOURCE = DotName.createSimple(VerbClientSource.class); + public static final DotName VERB_CLIENT_EMPTY = DotName.createSimple(VerbClientEmpty.class); + public static final String TEST_ANNOTATION = "xyz.block.ftl.java.test.FTLManaged"; + + @BuildStep + VerbClientBuildItem handleTopics(CombinedIndexBuildItem index, BuildProducer generatedClients, + BuildProducer generatedBeanBuildItemBuildProducer, + ModuleNameBuildItem moduleNameBuildItem, + LaunchModeBuildItem launchModeBuildItem) { + var clientDefinitions = index.getComputingIndex().getAnnotations(VerbClientDefinition.class); + Map clients = new HashMap<>(); + for (var clientDefinition : clientDefinitions) { + var iface = clientDefinition.target().asClass(); + if (!iface.isInterface()) { + throw new RuntimeException( + "@VerbClientDefinition can only be applied to interfaces and " + iface.name() + " is not an interface"); + } + String name = clientDefinition.value("name").asString(); + AnnotationValue moduleValue = clientDefinition.value("module"); + String module = moduleValue == null || moduleValue.asString().isEmpty() ? moduleNameBuildItem.getModuleName() + : moduleValue.asString(); + boolean found = false; + ClassOutput classOutput; + if (launchModeBuildItem.isTest()) { + //when running in tests we actually make these beans, so they can be injected into the tests + //the @TestResource qualifier is used so they can only be injected into test code + //TODO: is this the best way of handling this? revisit later + + classOutput = new GeneratedBeanGizmoAdaptor(generatedBeanBuildItemBuildProducer); + } else { + classOutput = new GeneratedClassGizmoAdaptor(generatedClients, true); + } + //TODO: map and list return types + for (var i : iface.interfaceTypes()) { + if (i.name().equals(VERB_CLIENT)) { + if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { + var returnType = i.asParameterizedType().arguments().get(1); + var paramType = i.asParameterizedType().arguments().get(0); + try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, + Object.class.getName(), iface.name().toString())) { + if (launchModeBuildItem.isTest()) { + cc.addAnnotation(TEST_ANNOTATION); + cc.addAnnotation(Singleton.class); + } + var publish = cc.getMethodCreator("call", returnType.name().toString(), + paramType.name().toString()); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + var results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(returnType.name().toString()), publish.load(false), publish.load(false)); + publish.returnValue(results); + publish = cc.getMethodCreator("call", Object.class, Object.class); + helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(returnType.name().toString()), publish.load(false), publish.load(false)); + publish.returnValue(results); + clients.put(iface.name(), + new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); + } + found = true; + break; + } else { + throw new RuntimeException( + "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " + + iface.name() + " does not have concrete type parameters"); + } + } else if (i.name().equals(VERB_CLIENT_SINK)) { + if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { + var paramType = i.asParameterizedType().arguments().get(0); + try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, + Object.class.getName(), iface.name().toString())) { + if (launchModeBuildItem.isTest()) { + cc.addAnnotation(TEST_ANNOTATION); + cc.addAnnotation(Singleton.class); + } + var publish = cc.getMethodCreator("call", void.class, paramType.name().toString()); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(Void.class), publish.load(false), publish.load(false)); + publish.returnVoid(); + publish = cc.getMethodCreator("call", void.class, Object.class); + helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(Void.class), publish.load(false), publish.load(false)); + publish.returnVoid(); + clients.put(iface.name(), + new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); + } + found = true; + break; + } else { + throw new RuntimeException( + "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " + + iface.name() + " does not have concrete type parameters"); + } + } else if (i.name().equals(VERB_CLIENT_SOURCE)) { + if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { + var returnType = i.asParameterizedType().arguments().get(0); + try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, + Object.class.getName(), iface.name().toString())) { + if (launchModeBuildItem.isTest()) { + cc.addAnnotation(TEST_ANNOTATION); + cc.addAnnotation(Singleton.class); + } + var publish = cc.getMethodCreator("call", returnType.name().toString()); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + var results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.loadNull(), + publish.loadClass(returnType.name().toString()), publish.load(false), publish.load(false)); + publish.returnValue(results); + + publish = cc.getMethodCreator("call", Object.class); + helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.loadNull(), + publish.loadClass(returnType.name().toString()), publish.load(false), publish.load(false)); + publish.returnValue(results); + clients.put(iface.name(), + new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); + } + found = true; + break; + } else { + throw new RuntimeException( + "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " + + iface.name() + " does not have concrete type parameters"); + } + } else if (i.name().equals(VERB_CLIENT_EMPTY)) { + try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, + Object.class.getName(), iface.name().toString())) { + if (launchModeBuildItem.isTest()) { + cc.addAnnotation(TEST_ANNOTATION); + cc.addAnnotation(Singleton.class); + } + var publish = cc.getMethodCreator("call", void.class); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.loadNull(), + publish.loadClass(Void.class), publish.load(false), publish.load(false)); + publish.returnVoid(); + clients.put(iface.name(), new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); + } + found = true; + break; + } + } + if (!found) { + throw new RuntimeException( + "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " + + iface.name() + " does not extend a verb client type"); + } + } + return new VerbClientBuildItem(clients); + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider b/java-runtime/ftl-runtime/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider new file mode 100644 index 0000000000..98be2f6c6f --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider @@ -0,0 +1 @@ +xyz.block.ftl.deployment.FTLCodeGenerator \ No newline at end of file diff --git a/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeDevModeTest.java b/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeDevModeTest.java new file mode 100644 index 0000000000..b2f045f4aa --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeDevModeTest.java @@ -0,0 +1,25 @@ +package xyz.block.ftl.java.runtime.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusDevModeTest; + +@Disabled +public class FtlJavaRuntimeDevModeTest { + + // Start hot reload (DevMode) test with your extension loaded + @RegisterExtension + static final QuarkusDevModeTest devModeTest = new QuarkusDevModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)); + + @Test + public void writeYourOwnDevModeTest() { + // Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information + Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName()); + } +} diff --git a/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeTest.java b/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeTest.java new file mode 100644 index 0000000000..45c2c2eef7 --- /dev/null +++ b/java-runtime/ftl-runtime/deployment/src/test/java/xyz/block/ftl/java/runtime/test/FtlJavaRuntimeTest.java @@ -0,0 +1,25 @@ +package xyz.block.ftl.java.runtime.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +@Disabled +public class FtlJavaRuntimeTest { + + // Start unit test with your extension loaded + @RegisterExtension + static final QuarkusUnitTest unitTest = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)); + + @Test + public void writeYourOwnUnitTest() { + // Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information + Assertions.assertTrue(true, "Add some assertions to " + getClass().getName()); + } +} diff --git a/java-runtime/ftl-runtime/integration-tests/pom.xml b/java-runtime/ftl-runtime/integration-tests/pom.xml new file mode 100644 index 0000000000..11c116b7c7 --- /dev/null +++ b/java-runtime/ftl-runtime/integration-tests/pom.xml @@ -0,0 +1,98 @@ + + + 4.0.0 + + + xyz.block + ftl-java-runtime-parent + 1.0.0-SNAPSHOT + + ftl-java-runtime-integration-tests + Ftl Java Runtime - Integration Tests + + + true + + + + + xyz.block + ftl-java-runtime + + + xyz.block + ftl-java-test-framework + test + + + io.rest-assured + rest-assured + test + + + io.quarkus + quarkus-junit5-mockito + + + + + + + io.quarkus + quarkus-maven-plugin + + + + build + generate-code + generate-code-tests + + + + + + maven-failsafe-plugin + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + native-image + + + native + + + + + + maven-surefire-plugin + + ${native.surefire.skip} + + + + + + false + true + + + + diff --git a/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/builtin.pb b/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/builtin.pb new file mode 100644 index 0000000000000000000000000000000000000000..83a40d59ed78a6001fcd9193855beb39946e4846 GIT binary patch literal 832 zcma)4O>fgc5G9G7q-*EPO`5?8Xtm;kDLJ^DI0gmvz@b8skaDw=1zT!tv%5yh-$3f` z0Kp$**6TE_)B`7bX5Ku{dw#?kHlg87mt}gZ-liEftCp*Intc;oO8SF~SZXfkTB+i**$Q0b zvSH>~%Y1hT0joCHUVG0~lJ8j8Z&w{RyufD%Csq-ur0#csgbVC|CjV-cs)P&5DuooY!MOe!qx%wn zf6Qrt|Cwj%l4d#9xk?sn9DC%MXY4pX+7Z4&;xQ82hF}t(BWSSED#qZ{DuNLiU}Fj` z%#6L-7wQn)HOS8fHlJ%BKSXMq)H$N5q|p;m)Dhll+$nzU!@a;kHXnU#AyN1ei@ literal 0 HcmV?d00001 diff --git a/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/echo.pb b/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/echo.pb new file mode 100644 index 0000000000000000000000000000000000000000..6f55e044cd45cffe47bed9cc276c5c3783b1e4c1 GIT binary patch literal 1440 zcmcJP&q~8U5XMbgT8Ikms<5OWOZ1dO7J{vKR9it2D$zM0XN(AHrZ0AY{-_ap>ld{2(tQ=9Y#u6ku+Uns673q^;XqitBUhBaUC`H6H=5xINW3)q>VLm zxt~7_%e(VgS%7LS@nSHawDF^AD_XdL)H~3^$QoIf>PZ-L64rM`|5D9)9oKU&S4uC% zEKLMB4+{`MjTnUR7%ZUkH?VG9TUUy?=VXlEPg@@q^sbsp8*9iez~@sXGoA?I5yk=J yG-2d6Uob?5K>UnzNFcng_Y)g|;&R(~8~q(=V=m-`qlt1M2mR}}Qt1a?bkdsu literal 0 HcmV?d00001 diff --git a/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/time.pb b/java-runtime/ftl-runtime/integration-tests/src/main/ftl-module-schema/time.pb new file mode 100644 index 0000000000000000000000000000000000000000..5388d67667f6b803bee1b8617387572791565c8c GIT binary patch literal 695 zcmd;L5K?x|Pf1lsPt8j$N-RlDQAny(a0~I#Q*iND@beE*aCPwv(Nkh6$;?gFI?Bj( zh> { +} diff --git a/java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/Person.java b/java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/Person.java new file mode 100644 index 0000000000..d7233db37a --- /dev/null +++ b/java-runtime/ftl-runtime/integration-tests/src/main/java/xyz/block/ftl/java/runtime/it/Person.java @@ -0,0 +1,5 @@ +package xyz.block.ftl.java.runtime.it; + +public record Person(String first, String last) { + +} diff --git a/java-runtime/ftl-runtime/integration-tests/src/main/resources/application.properties b/java-runtime/ftl-runtime/integration-tests/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/java-runtime/ftl-runtime/integration-tests/src/test/java/xyz/block/ftl/java/runtime/it/FtlJavaRuntimeResourceTest.java b/java-runtime/ftl-runtime/integration-tests/src/test/java/xyz/block/ftl/java/runtime/it/FtlJavaRuntimeResourceTest.java new file mode 100644 index 0000000000..ef47c2b6a1 --- /dev/null +++ b/java-runtime/ftl-runtime/integration-tests/src/test/java/xyz/block/ftl/java/runtime/it/FtlJavaRuntimeResourceTest.java @@ -0,0 +1,62 @@ +package xyz.block.ftl.java.runtime.it; + +import java.util.function.Function; + +import jakarta.inject.Inject; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import ftl.echo.EchoClient; +import ftl.echo.EchoRequest; +import ftl.echo.EchoResponse; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import xyz.block.ftl.VerbClient; +import xyz.block.ftl.VerbClientDefinition; +import xyz.block.ftl.VerbClientSink; +import xyz.block.ftl.java.test.FTLManaged; +import xyz.block.ftl.java.test.internal.FTLTestResource; +import xyz.block.ftl.java.test.internal.TestVerbServer; + +@QuarkusTest +@QuarkusTestResource(FTLTestResource.class) +public class FtlJavaRuntimeResourceTest { + + @FTLManaged + @Inject + PublishVerbClient myVerbClient; + + @FTLManaged + @Inject + HelloClient helloClient; + + @Test + public void testHelloEndpoint() { + TestVerbServer.registerFakeVerb("echo", "echo", new Function() { + @Override + public EchoResponse apply(EchoRequest s) { + return new EchoResponse(s.getName()); + } + }); + EchoClient echoClient = Mockito.mock(EchoClient.class); + Mockito.when(echoClient.call(Mockito.any())).thenReturn(new EchoResponse().setMessage("Stuart")); + Assertions.assertEquals("Hello Stuart", helloClient.call("Stuart")); + } + + @Test + @Disabled + public void testTopic() { + myVerbClient.call(new Person("Stuart", "Douglas")); + } + + @VerbClientDefinition(name = "publish") + interface PublishVerbClient extends VerbClientSink { + } + + @VerbClientDefinition(name = "hello") + interface HelloClient extends VerbClient { + } +} diff --git a/java-runtime/ftl-runtime/pom.xml b/java-runtime/ftl-runtime/pom.xml new file mode 100644 index 0000000000..4ff40b3f4f --- /dev/null +++ b/java-runtime/ftl-runtime/pom.xml @@ -0,0 +1,264 @@ + + + 4.0.0 + xyz.block + ftl-java-runtime-parent + 1.0.0-SNAPSHOT + pom + Ftl Java Runtime - Parent + + + deployment + runtime + integration-tests + test-framework + + + + 3.13.0 + ${surefire-plugin.version} + 17 + UTF-8 + UTF-8 + 3.12.3 + 3.2.5 + ${basedir}/../../.. + 1.65.1 + 1.13.0 + 2.24.1 + 1.11.0 + + + + + + io.quarkus + quarkus-bom + ${quarkus.version} + pom + import + + + xyz.block + ftl-java-runtime + ${project.version} + + + xyz.block + ftl-java-runtime-deployment + ${project.version} + + + xyz.block + ftl-java-test-framework + ${project.version} + + + io.grpc + grpc-bom + ${grpc.version} + pom + import + + + + com.squareup + javapoet + ${javapoet.version} + + + + com.squareup.wire + wire-runtime-jvm + ${wire.version} + + + com.squareup.wire + wire-grpc-server + ${wire.version} + + + com.squareup.wire + wire-grpc-client-jvm + ${wire.version} + + + + + io.grpc + grpc-netty + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + + + + + + + io.quarkus + quarkus-maven-plugin + ${quarkus.version} + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + ${settings.localRepository} + + + + + maven-failsafe-plugin + ${failsafe-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + ${settings.localRepository} + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + net.revelc.code.formatter + formatter-maven-plugin + ${version.formatter.plugin} + + + quarkus-ide-config + io.quarkus + ${quarkus.version} + + + + + .cache/formatter-maven-plugin-${version.formatter.plugin} + eclipse-format.xml + LF + ${format.skip} + + + + net.revelc.code + impsort-maven-plugin + ${version.impsort.plugin} + + + .cache/impsort-maven-plugin-${version.impsort.plugin} + java.,javax.,jakarta.,org.,com. + * + ${format.skip} + true + + + + + + + + + + format + + true + + !no-format + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + process-sources + + format + + + + + + net.revelc.code + impsort-maven-plugin + + true + + + + sort-imports + + sort + + + + + + + + + validate + + true + + no-format + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + process-sources + + validate + + + + + + net.revelc.code + impsort-maven-plugin + + true + + + + check-imports + + check + + + + + + + + + diff --git a/java-runtime/ftl-runtime/runtime/pom.xml b/java-runtime/ftl-runtime/runtime/pom.xml new file mode 100644 index 0000000000..9ea5ec0c64 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/pom.xml @@ -0,0 +1,137 @@ + + + 4.0.0 + + + xyz.block + ftl-java-runtime-parent + 1.0.0-SNAPSHOT + + ftl-java-runtime + Ftl Java Runtime - Runtime + + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-grpc + + + io.quarkus + quarkus-rest-jackson + + + com.fasterxml.jackson.module + jackson-module-kotlin + + + io.grpc + grpc-stub + + + io.grpc + grpc-services + + + + io.grpc + grpc-netty + + + io.grpc + grpc-protobuf + + + javax.annotation + javax.annotation-api + + + org.jetbrains + annotations + + + + + + + kr.motd.maven + os-maven-plugin + 1.6.0 + + + + + io.quarkus + quarkus-extension-maven-plugin + ${quarkus.version} + + + compile + + extension-descriptor + + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + generate-sources + + add-source + + + + ${project.basedir}/target/generated-sources/protoc + + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + + + compile + compile-custom + test-compile + test-compile-custom + + + + + com.google.protobuf:protoc:3.25.4:exe:${os.detected.classifier} + ${rootDir}/backend/protos + grpc-java + io.grpc:protoc-gen-grpc-java:1.65.1:exe:${os.detected.classifier} + + + + + diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Config.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Config.java new file mode 100644 index 0000000000..f757472983 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Config.java @@ -0,0 +1,12 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Config { + String value(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Cron.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Cron.java new file mode 100644 index 0000000000..31ffc34218 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Cron.java @@ -0,0 +1,14 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Cron { + + String value(); + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Export.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Export.java new file mode 100644 index 0000000000..63354ad057 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Export.java @@ -0,0 +1,14 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks the given item as exported in the FTL schema. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER }) +public @interface Export { +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/GeneratedRef.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/GeneratedRef.java new file mode 100644 index 0000000000..2b24f59af4 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/GeneratedRef.java @@ -0,0 +1,11 @@ +package xyz.block.ftl; + +/** + * Indicates that the class was generated from an external module. + */ +public @interface GeneratedRef { + + String name(); + + String module(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Retry.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Retry.java new file mode 100644 index 0000000000..19752db1e6 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Retry.java @@ -0,0 +1,20 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +public @interface Retry { + int count() default 0; + + String minBackoff() default ""; + + String maxBackoff() default ""; + + String catchModule() default ""; + + String catchVerb() default ""; +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Secret.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Secret.java new file mode 100644 index 0000000000..12d61ce1d2 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Secret.java @@ -0,0 +1,12 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Secret { + String value(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Subscription.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Subscription.java new file mode 100644 index 0000000000..9b2283f5e0 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Subscription.java @@ -0,0 +1,28 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +public @interface Subscription { + /** + * @return The module of the topic to subscribe to, if empty then the topic is assumed to be in the current module. + */ + String module() default ""; + + /** + * + * @return The name of the topic to subscribe to. + */ + String topic(); + + /** + * + * @return The subscription name + */ + String name(); + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Topic.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Topic.java new file mode 100644 index 0000000000..16170fe24e --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Topic.java @@ -0,0 +1,12 @@ +package xyz.block.ftl; + +/** + * A concrete definition of a topic. Extend this interface and annotate with {@code @TopicDefinition} to define a topic, + * then inject this into verb methods to publish to the topic. + * + * @param + */ +public interface Topic { + + void publish(T object); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/TopicDefinition.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/TopicDefinition.java new file mode 100644 index 0000000000..a6482006d6 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/TopicDefinition.java @@ -0,0 +1,17 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface TopicDefinition { + /** + * + * @return The name of the topic + */ + String name(); + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Verb.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Verb.java new file mode 100644 index 0000000000..c421a34fd1 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/Verb.java @@ -0,0 +1,15 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * A FTL verb. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Verb { + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClient.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClient.java new file mode 100644 index 0000000000..b179357c89 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClient.java @@ -0,0 +1,17 @@ +package xyz.block.ftl; + +/** + * A client for a specific verb. + * + * The sink source and empty interfaces allow for different call signatures. + * + * TODO: should these be top level + * + * @param

The verb parameter type + * @param The verb return type + */ +public interface VerbClient { + + R call(P param); + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java new file mode 100644 index 0000000000..1e258f7fa6 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java @@ -0,0 +1,18 @@ +package xyz.block.ftl; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation that is used to define a verb client + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface VerbClientDefinition { + + String module() default ""; + + String name(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java new file mode 100644 index 0000000000..2d68c8d88d --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java @@ -0,0 +1,5 @@ +package xyz.block.ftl; + +public interface VerbClientEmpty { + void call(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java new file mode 100644 index 0000000000..cb05af1038 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java @@ -0,0 +1,5 @@ +package xyz.block.ftl; + +public interface VerbClientSink

{ + void call(P param); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java new file mode 100644 index 0000000000..95efc04c78 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java @@ -0,0 +1,5 @@ +package xyz.block.ftl; + +public interface VerbClientSource { + R call(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbName.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbName.java new file mode 100644 index 0000000000..1a9a7e2548 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/VerbName.java @@ -0,0 +1,12 @@ +package xyz.block.ftl; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Used to override the name of a verb. Without this annotation it defaults to the method name. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface VerbName { + String value(); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLConfigSource.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLConfigSource.java new file mode 100644 index 0000000000..15ff77949d --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLConfigSource.java @@ -0,0 +1,65 @@ +package xyz.block.ftl.runtime; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Set; + +import org.eclipse.microprofile.config.spi.ConfigSource; + +public class FTLConfigSource implements ConfigSource { + + final static String SEPARATE_SERVER = "quarkus.grpc.server.use-separate-server"; + final static String PORT = "quarkus.http.port"; + final static String HOST = "quarkus.http.host"; + + final static String FTL_BIND = "FTL_BIND"; + + @Override + public Set getPropertyNames() { + return Set.of(SEPARATE_SERVER, PORT, HOST); + } + + @Override + public int getOrdinal() { + return 1; + } + + @Override + public String getValue(String s) { + switch (s) { + case SEPARATE_SERVER -> { + return "false"; + } + case PORT -> { + String bind = System.getenv(FTL_BIND); + if (bind == null) { + return null; + } + try { + URI uri = new URI(bind); + return Integer.toString(uri.getPort()); + } catch (URISyntaxException e) { + return null; + } + } + case HOST -> { + String bind = System.getenv(FTL_BIND); + if (bind == null) { + return null; + } + try { + URI uri = new URI(bind); + return uri.getHost(); + } catch (URISyntaxException e) { + return null; + } + } + } + return null; + } + + @Override + public String getName() { + return "FTL Config"; + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java new file mode 100644 index 0000000000..28b65e3cd9 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java @@ -0,0 +1,182 @@ +package xyz.block.ftl.runtime; + +import java.net.URI; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import jakarta.inject.Singleton; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import com.google.protobuf.ByteString; + +import io.grpc.ManagedChannelBuilder; +import io.grpc.stub.StreamObserver; +import io.quarkus.runtime.Startup; +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.CallResponse; +import xyz.block.ftl.v1.ModuleContextRequest; +import xyz.block.ftl.v1.ModuleContextResponse; +import xyz.block.ftl.v1.PublishEventRequest; +import xyz.block.ftl.v1.PublishEventResponse; +import xyz.block.ftl.v1.VerbServiceGrpc; +import xyz.block.ftl.v1.schema.Ref; + +@Singleton +@Startup +public class FTLController { + private static final Logger log = Logger.getLogger(FTLController.class); + final String moduleName; + + private Throwable currentError; + private volatile ModuleContextResponse moduleContextResponse; + private boolean waiters = false; + + final VerbServiceGrpc.VerbServiceStub verbService; + final StreamObserver moduleObserver = new StreamObserver<>() { + @Override + public void onNext(ModuleContextResponse moduleContextResponse) { + synchronized (this) { + currentError = null; + FTLController.this.moduleContextResponse = moduleContextResponse; + if (waiters) { + this.notifyAll(); + waiters = false; + } + } + + } + + @Override + public void onError(Throwable throwable) { + log.error("GRPC connection error", throwable); + synchronized (this) { + currentError = throwable; + if (waiters) { + this.notifyAll(); + waiters = false; + } + } + } + + @Override + public void onCompleted() { + verbService.getModuleContext(ModuleContextRequest.newBuilder().setModule(moduleName).build(), moduleObserver); + } + }; + + public FTLController(@ConfigProperty(name = "ftl.endpoint", defaultValue = "http://localhost:8892") URI uri, + @ConfigProperty(name = "ftl.module.name") String moduleName) { + this.moduleName = moduleName; + var channelBuilder = ManagedChannelBuilder.forAddress(uri.getHost(), uri.getPort()); + if (uri.getScheme().equals("http")) { + channelBuilder.usePlaintext(); + } + var channel = channelBuilder.build(); + verbService = VerbServiceGrpc.newStub(channel); + verbService.getModuleContext(ModuleContextRequest.newBuilder().setModule(moduleName).build(), moduleObserver); + + } + + public byte[] getSecret(String secretName) { + var context = getModuleContext(); + if (context.containsSecrets(secretName)) { + return context.getSecretsMap().get(secretName).toByteArray(); + } + throw new RuntimeException("Secret not found: " + secretName); + } + + public byte[] getConfig(String secretName) { + var context = getModuleContext(); + if (context.containsConfigs(secretName)) { + return context.getConfigsMap().get(secretName).toByteArray(); + } + throw new RuntimeException("Config not found: " + secretName); + } + + public byte[] callVerb(String name, String module, byte[] payload) { + CompletableFuture cf = new CompletableFuture<>(); + verbService.call(CallRequest.newBuilder().setVerb(Ref.newBuilder().setModule(module).setName(name)) + .setBody(ByteString.copyFrom(payload)).build(), new StreamObserver<>() { + + @Override + public void onNext(CallResponse callResponse) { + if (callResponse.hasError()) { + cf.completeExceptionally(new RuntimeException(callResponse.getError().getMessage())); + } else { + cf.complete(callResponse.getBody().toByteArray()); + } + } + + @Override + public void onError(Throwable throwable) { + cf.completeExceptionally(throwable); + } + + @Override + public void onCompleted() { + + } + }); + try { + return cf.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void publishEvent(String topic, String callingVerbName, byte[] event) { + CompletableFuture cf = new CompletableFuture<>(); + verbService.publishEvent(PublishEventRequest.newBuilder() + .setCaller(callingVerbName).setBody(ByteString.copyFrom(event)) + .setTopic(Ref.newBuilder().setModule(moduleName).setName(topic).build()).build(), + new StreamObserver() { + @Override + public void onNext(PublishEventResponse publishEventResponse) { + cf.complete(null); + } + + @Override + public void onError(Throwable throwable) { + cf.completeExceptionally(throwable); + } + + @Override + public void onCompleted() { + cf.complete(null); + } + }); + try { + cf.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private ModuleContextResponse getModuleContext() { + var moduleContext = moduleContextResponse; + if (moduleContext != null) { + return moduleContext; + } + synchronized (moduleObserver) { + for (;;) { + moduleContext = moduleContextResponse; + if (moduleContext != null) { + return moduleContext; + } + if (currentError != null) { + throw new RuntimeException(currentError); + } + waiters = true; + try { + moduleObserver.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + } + } + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLHttpHandler.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLHttpHandler.java new file mode 100644 index 0000000000..48596bffe5 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLHttpHandler.java @@ -0,0 +1,245 @@ +package xyz.block.ftl.runtime; + +import java.io.ByteArrayOutputStream; +import java.net.InetSocketAddress; +import java.nio.channels.Channels; +import java.nio.channels.WritableByteChannel; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +import jakarta.inject.Singleton; +import jakarta.ws.rs.core.MediaType; + +import org.jboss.logging.Logger; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.ByteString; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.FileRegion; +import io.netty.handler.codec.http.*; +import io.netty.util.ReferenceCountUtil; +import io.quarkus.netty.runtime.virtual.VirtualClientConnection; +import io.quarkus.netty.runtime.virtual.VirtualResponseHandler; +import io.quarkus.vertx.http.runtime.QuarkusHttpHeaders; +import io.quarkus.vertx.http.runtime.VertxHttpRecorder; +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.CallResponse; + +@SuppressWarnings("unused") +@Singleton +public class FTLHttpHandler implements VerbInvoker { + + public static final String CONTENT_TYPE = "Content-Type"; + final ObjectMapper mapper; + private static final Logger log = Logger.getLogger("quarkus.amazon.lambda.http"); + + private static final int BUFFER_SIZE = 8096; + + private static final Map> ERROR_HEADERS = Map.of(); + + private static final String COOKIE_HEADER = "Cookie"; + + // comma headers for headers that have comma in value and we don't want to split it up into + // multiple headers + private static final Set COMMA_HEADERS = Set.of("access-control-request-headers"); + + public FTLHttpHandler(ObjectMapper mapper) { + this.mapper = mapper; + } + + @Override + public CallResponse handle(CallRequest in) { + try { + var body = mapper.createParser(in.getBody().newInput()) + .readValueAs(xyz.block.ftl.runtime.builtin.HttpRequest.class); + body.getHeaders().put(FTLRecorder.X_FTL_VERB, List.of(in.getVerb().getName())); + var ret = handleRequest(body); + var mappedResponse = mapper.writer().writeValueAsBytes(ret); + return CallResponse.newBuilder().setBody(ByteString.copyFrom(mappedResponse)).build(); + } catch (Exception e) { + return CallResponse.newBuilder().setError(CallResponse.Error.newBuilder().setMessage(e.getMessage()).build()) + .build(); + } + + } + + public xyz.block.ftl.runtime.builtin.HttpResponse handleRequest(xyz.block.ftl.runtime.builtin.HttpRequest request) { + InetSocketAddress clientAddress = null; + try { + return nettyDispatch(clientAddress, request); + } catch (Exception e) { + log.error("Request Failure", e); + xyz.block.ftl.runtime.builtin.HttpResponse res = new xyz.block.ftl.runtime.builtin.HttpResponse(); + res.setStatus(500); + res.setError(e); + res.setHeaders(ERROR_HEADERS); + return res; + } + + } + + private class NettyResponseHandler implements VirtualResponseHandler { + xyz.block.ftl.runtime.builtin.HttpResponse responseBuilder = new xyz.block.ftl.runtime.builtin.HttpResponse(); + ByteArrayOutputStream baos; + WritableByteChannel byteChannel; + final xyz.block.ftl.runtime.builtin.HttpRequest request; + CompletableFuture future = new CompletableFuture<>(); + + public NettyResponseHandler(xyz.block.ftl.runtime.builtin.HttpRequest request) { + this.request = request; + } + + public CompletableFuture getFuture() { + return future; + } + + @Override + public void handleMessage(Object msg) { + try { + //log.info("Got message: " + msg.getClass().getName()); + + if (msg instanceof HttpResponse) { + HttpResponse res = (HttpResponse) msg; + responseBuilder.setStatus(res.status().code()); + + final Map> headers = new HashMap<>(); + responseBuilder.setHeaders(headers); + for (String name : res.headers().names()) { + final List allForName = res.headers().getAll(name); + if (allForName == null || allForName.isEmpty()) { + continue; + } + headers.put(name, allForName); + } + } + if (msg instanceof HttpContent) { + HttpContent content = (HttpContent) msg; + int readable = content.content().readableBytes(); + if (baos == null && readable > 0) { + baos = createByteStream(); + } + for (int i = 0; i < readable; i++) { + baos.write(content.content().readByte()); + } + } + if (msg instanceof FileRegion) { + FileRegion file = (FileRegion) msg; + if (file.count() > 0 && file.transferred() < file.count()) { + if (baos == null) + baos = createByteStream(); + if (byteChannel == null) + byteChannel = Channels.newChannel(baos); + file.transferTo(byteChannel, file.transferred()); + } + } + if (msg instanceof LastHttpContent) { + if (baos != null) { + List ct = responseBuilder.getHeaders().get(CONTENT_TYPE); + if (ct == null || ct.isEmpty()) { + //TODO: how to handle this + responseBuilder.setBody(baos.toString(StandardCharsets.UTF_8)); + } else if (ct.get(0).contains(MediaType.TEXT_PLAIN)) { + // need to encode as JSON string + responseBuilder.setBody(mapper.writer().writeValueAsString(baos.toString(StandardCharsets.UTF_8))); + } else { + responseBuilder.setBody(baos.toString(StandardCharsets.UTF_8)); + } + } + future.complete(responseBuilder); + } + } catch (Throwable ex) { + future.completeExceptionally(ex); + } finally { + if (msg != null) { + ReferenceCountUtil.release(msg); + } + } + } + + @Override + public void close() { + if (!future.isDone()) + future.completeExceptionally(new RuntimeException("Connection closed")); + } + } + + private xyz.block.ftl.runtime.builtin.HttpResponse nettyDispatch(InetSocketAddress clientAddress, + xyz.block.ftl.runtime.builtin.HttpRequest request) + throws Exception { + QuarkusHttpHeaders quarkusHeaders = new QuarkusHttpHeaders(); + quarkusHeaders.setContextObject(xyz.block.ftl.runtime.builtin.HttpRequest.class, request); + HttpMethod httpMethod = HttpMethod.valueOf(request.getMethod()); + if (httpMethod == null) { + throw new IllegalStateException("Missing HTTP method in request event"); + } + //TODO: encoding schenanigans + StringBuilder path = new StringBuilder(request.getPath()); + if (request.getQuery() != null && !request.getQuery().isEmpty()) { + path.append("?"); + var first = true; + for (var entry : request.getQuery().entrySet()) { + for (var val : entry.getValue()) { + if (first) { + first = false; + } else { + path.append("&"); + } + path.append(entry.getKey()).append("=").append(val); + } + } + } + DefaultHttpRequest nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, + httpMethod, path.toString(), quarkusHeaders); + if (request.getHeaders() != null) { + for (Map.Entry> header : request.getHeaders().entrySet()) { + if (header.getValue() != null) { + for (String val : header.getValue()) { + nettyRequest.headers().add(header.getKey(), val); + } + } + } + } + nettyRequest.headers().add(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + if (!nettyRequest.headers().contains(HttpHeaderNames.HOST)) { + nettyRequest.headers().add(HttpHeaderNames.HOST, "localhost"); + } + + HttpContent requestContent = LastHttpContent.EMPTY_LAST_CONTENT; + if (request.getBody() != null) { + // See https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3 + nettyRequest.headers().add(HttpHeaderNames.TRANSFER_ENCODING, "chunked"); + ByteBuf body = Unpooled.copiedBuffer(request.getBody().toString(), StandardCharsets.UTF_8); //TODO: do we need to look at the request encoding? + requestContent = new DefaultLastHttpContent(body); + } + NettyResponseHandler handler = new NettyResponseHandler(request); + VirtualClientConnection connection = VirtualClientConnection.connect(handler, VertxHttpRecorder.VIRTUAL_HTTP, + clientAddress); + + connection.sendMessage(nettyRequest); + connection.sendMessage(requestContent); + try { + return handler.getFuture().get(); + } finally { + connection.close(); + } + } + + private ByteArrayOutputStream createByteStream() { + ByteArrayOutputStream baos; + baos = new ByteArrayOutputStream(BUFFER_SIZE); + return baos; + } + + private boolean isBinary(String contentType) { + if (contentType != null) { + String ct = contentType.toLowerCase(Locale.ROOT); + return !(ct.startsWith("text") || ct.contains("json") || ct.contains("xml") || ct.contains("yaml")); + } + return false; + } + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java new file mode 100644 index 0000000000..6b839518c1 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java @@ -0,0 +1,110 @@ +package xyz.block.ftl.runtime; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.function.BiFunction; + +import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext; +import org.jboss.resteasy.reactive.server.core.parameters.ParameterExtractor; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkus.arc.Arc; +import io.quarkus.runtime.annotations.Recorder; +import xyz.block.ftl.v1.CallRequest; + +@Recorder +public class FTLRecorder { + + public static final String X_FTL_VERB = "X-ftl-verb"; + + public void registerVerb(String module, String verbName, String methodName, List> parameterTypes, + Class verbHandlerClass, List> paramMappers) { + //TODO: this sucks + try { + var method = verbHandlerClass.getDeclaredMethod(methodName, parameterTypes.toArray(new Class[0])); + var handlerInstance = Arc.container().instance(verbHandlerClass); + Arc.container().instance(VerbRegistry.class).get().register(module, verbName, handlerInstance, method, + paramMappers); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void registerHttpIngress(String module, String verbName) { + try { + Arc.container().instance(VerbRegistry.class).get().register(module, verbName, + Arc.container().instance(FTLHttpHandler.class).get()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public BiFunction topicSupplier(String className, String callingVerb) { + try { + var cls = Thread.currentThread().getContextClassLoader().loadClass(className.replace("/", ".")); + var topic = cls.getDeclaredConstructor(String.class).newInstance(callingVerb); + return new BiFunction() { + @Override + public Object apply(ObjectMapper mapper, CallRequest callRequest) { + return topic; + } + }; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public BiFunction verbClientSupplier(String className) { + try { + var cls = Thread.currentThread().getContextClassLoader().loadClass(className.replace("/", ".")); + var client = cls.getDeclaredConstructor().newInstance(); + return new BiFunction() { + @Override + public Object apply(ObjectMapper mapper, CallRequest callRequest) { + return client; + } + }; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ParameterExtractor topicParamExtractor(String className) { + + try { + var cls = Thread.currentThread().getContextClassLoader().loadClass(className.replace("/", ".")); + Constructor ctor = cls.getDeclaredConstructor(String.class); + return new ParameterExtractor() { + @Override + public Object extractParameter(ResteasyReactiveRequestContext context) { + + try { + Object topic = ctor.newInstance(context.getHeader(X_FTL_VERB, true)); + return topic; + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + }; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ParameterExtractor verbParamExtractor(String className) { + try { + var cls = Thread.currentThread().getContextClassLoader().loadClass(className.replace("/", ".")); + var client = cls.getDeclaredConstructor().newInstance(); + return new ParameterExtractor() { + @Override + public Object extractParameter(ResteasyReactiveRequestContext context) { + return client; + } + }; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/TopicHelper.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/TopicHelper.java new file mode 100644 index 0000000000..aa1e0fb20b --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/TopicHelper.java @@ -0,0 +1,32 @@ +package xyz.block.ftl.runtime; + +import jakarta.inject.Singleton; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkus.arc.Arc; + +@Singleton +public class TopicHelper { + + final FTLController controller; + final ObjectMapper mapper; + + public TopicHelper(FTLController controller, ObjectMapper mapper) { + this.controller = controller; + this.mapper = mapper; + } + + public void publish(String topic, String verb, Object message) { + try { + controller.publishEvent(topic, verb, mapper.writeValueAsBytes(message)); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public static TopicHelper instance() { + return Arc.container().instance(TopicHelper.class).get(); + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbClientHelper.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbClientHelper.java new file mode 100644 index 0000000000..b28037c76c --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbClientHelper.java @@ -0,0 +1,48 @@ +package xyz.block.ftl.runtime; + +import java.util.Map; + +import jakarta.inject.Singleton; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkus.arc.Arc; + +@Singleton +public class VerbClientHelper { + + final FTLController controller; + final ObjectMapper mapper; + + public VerbClientHelper(FTLController controller, ObjectMapper mapper) { + this.controller = controller; + this.mapper = mapper; + } + + public Object call(String verb, String module, Object message, Class returnType, boolean listReturnType, + boolean mapReturnType) { + try { + if (message == null) { + //Unit must be an empty map + //TODO: what about optional? + message = Map.of(); + } + var result = controller.callVerb(verb, module, mapper.writeValueAsBytes(message)); + if (listReturnType) { + return mapper.readerForArrayOf(returnType).readValue(result); + } else if (mapReturnType) { + return mapper.readerForMapOf(returnType).readValue(result); + } + if (result == null) { + return null; + } + return mapper.readerFor(returnType).readValue(result); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static VerbClientHelper instance() { + return Arc.container().instance(VerbClientHelper.class).get(); + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java new file mode 100644 index 0000000000..714f197a05 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java @@ -0,0 +1,51 @@ +package xyz.block.ftl.runtime; + +import jakarta.inject.Singleton; + +import io.grpc.stub.StreamObserver; +import io.quarkus.grpc.GrpcService; +import xyz.block.ftl.v1.*; + +@Singleton +@GrpcService +public class VerbHandler extends VerbServiceGrpc.VerbServiceImplBase { + + final VerbRegistry registry; + + public VerbHandler(VerbRegistry registry) { + this.registry = registry; + } + + @Override + public void call(CallRequest request, StreamObserver responseObserver) { + var response = registry.invoke(request); + responseObserver.onNext(response); + responseObserver.onCompleted(); + } + + @Override + public void publishEvent(PublishEventRequest request, StreamObserver responseObserver) { + super.publishEvent(request, responseObserver); + } + + @Override + public void sendFSMEvent(SendFSMEventRequest request, StreamObserver responseObserver) { + super.sendFSMEvent(request, responseObserver); + } + + @Override + public StreamObserver acquireLease(StreamObserver responseObserver) { + return super.acquireLease(responseObserver); + } + + @Override + public void getModuleContext(ModuleContextRequest request, StreamObserver responseObserver) { + super.getModuleContext(request, responseObserver); + } + + @Override + public void ping(PingRequest request, StreamObserver responseObserver) { + responseObserver.onNext(PingResponse.newBuilder().build()); + responseObserver.onCompleted(); + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbInvoker.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbInvoker.java new file mode 100644 index 0000000000..d27c233dcd --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbInvoker.java @@ -0,0 +1,9 @@ +package xyz.block.ftl.runtime; + +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.CallResponse; + +public interface VerbInvoker { + + CallResponse handle(CallRequest in); +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java new file mode 100644 index 0000000000..a0202690b4 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java @@ -0,0 +1,179 @@ +package xyz.block.ftl.runtime; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; + +import jakarta.inject.Singleton; + +import org.jboss.logging.Logger; +import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext; +import org.jboss.resteasy.reactive.server.core.parameters.ParameterExtractor; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.ByteString; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.InstanceHandle; +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.CallResponse; + +@Singleton +public class VerbRegistry { + + private static final Logger log = Logger.getLogger(VerbRegistry.class); + + final ObjectMapper mapper; + + private final Map verbs = new ConcurrentHashMap<>(); + + public VerbRegistry(ObjectMapper mapper) { + this.mapper = mapper; + } + + public void register(String module, String name, InstanceHandle verbHandlerClass, Method method, + List> paramMappers) { + verbs.put(new Key(module, name), new AnnotatedEndpointHandler(verbHandlerClass, method, paramMappers)); + } + + public void register(String module, String name, VerbInvoker verbInvoker) { + verbs.put(new Key(module, name), verbInvoker); + } + + public CallResponse invoke(CallRequest request) { + VerbInvoker handler = verbs.get(new Key(request.getVerb().getModule(), request.getVerb().getName())); + if (handler == null) { + return CallResponse.newBuilder().setError(CallResponse.Error.newBuilder().setMessage("Verb not found").build()) + .build(); + } + return handler.handle(request); + } + + private record Key(String module, String name) { + + } + + private class AnnotatedEndpointHandler implements VerbInvoker { + final InstanceHandle verbHandlerClass; + final Method method; + final List> parameterSuppliers; + + private AnnotatedEndpointHandler(InstanceHandle verbHandlerClass, Method method, + List> parameterSuppliers) { + this.verbHandlerClass = verbHandlerClass; + this.method = method; + this.parameterSuppliers = parameterSuppliers; + } + + public CallResponse handle(CallRequest in) { + try { + Object[] params = new Object[parameterSuppliers.size()]; + for (int i = 0; i < parameterSuppliers.size(); i++) { + params[i] = parameterSuppliers.get(i).apply(mapper, in); + } + Object ret; + ret = method.invoke(verbHandlerClass.get(), params); + var mappedResponse = mapper.writer().writeValueAsBytes(ret); + return CallResponse.newBuilder().setBody(ByteString.copyFrom(mappedResponse)).build(); + } catch (Exception e) { + log.errorf(e, "Failed to invoke verb %s.%s", in.getVerb().getModule(), in.getVerb().getName()); + return CallResponse.newBuilder().setError(CallResponse.Error.newBuilder().setMessage(e.getMessage()).build()) + .build(); + } + } + } + + public record BodySupplier(Class inputClass) implements BiFunction { + + @Override + public Object apply(ObjectMapper mapper, CallRequest in) { + try { + return mapper.createParser(in.getBody().newInput()).readValueAs(inputClass); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public static class SecretSupplier implements BiFunction, ParameterExtractor { + + final String name; + final Class inputClass; + + volatile FTLController ftlController; + + public SecretSupplier(String name, Class inputClass) { + this.name = name; + this.inputClass = inputClass; + } + + @Override + public Object apply(ObjectMapper mapper, CallRequest in) { + if (ftlController == null) { + ftlController = Arc.container().instance(FTLController.class).get(); + } + var secret = ftlController.getSecret(name); + try { + return mapper.createParser(secret).readValueAs(inputClass); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public String getName() { + return name; + } + + public Class getInputClass() { + return inputClass; + } + + @Override + public Object extractParameter(ResteasyReactiveRequestContext context) { + return apply(Arc.container().instance(ObjectMapper.class).get(), null); + } + } + + public static class ConfigSupplier implements BiFunction, ParameterExtractor { + + final String name; + final Class inputClass; + + volatile FTLController ftlController; + + public ConfigSupplier(String name, Class inputClass) { + this.name = name; + this.inputClass = inputClass; + } + + @Override + public Object apply(ObjectMapper mapper, CallRequest in) { + if (ftlController == null) { + ftlController = Arc.container().instance(FTLController.class).get(); + } + var secret = ftlController.getConfig(name); + try { + return mapper.createParser(secret).readValueAs(inputClass); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object extractParameter(ResteasyReactiveRequestContext context) { + return apply(Arc.container().instance(ObjectMapper.class).get(), null); + } + + public Class getInputClass() { + return inputClass; + } + + public String getName() { + return name; + } + } + +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpRequest.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpRequest.java new file mode 100644 index 0000000000..59b5d97c60 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpRequest.java @@ -0,0 +1,66 @@ +package xyz.block.ftl.runtime.builtin; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * TODO: should this be generated? + */ +public class HttpRequest { + private String method; + private String path; + private Map pathParameters; + private Map> query; + private Map> headers; + private JsonNode body; + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Map getPathParameters() { + return pathParameters; + } + + public void setPathParameters(Map pathParameters) { + this.pathParameters = pathParameters; + } + + public Map> getQuery() { + return query; + } + + public void setQuery(Map> query) { + this.query = query; + } + + public Map> getHeaders() { + return headers; + } + + public void setHeaders(Map> headers) { + this.headers = headers; + } + + public JsonNode getBody() { + return body; + } + + public void setBody(JsonNode body) { + this.body = body; + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpResponse.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpResponse.java new file mode 100644 index 0000000000..6db4d8aaf9 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/builtin/HttpResponse.java @@ -0,0 +1,49 @@ +package xyz.block.ftl.runtime.builtin; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonRawValue; + +/** + * TODO: should this be generated + */ +public class HttpResponse { + private long status; + private Map> headers; + @JsonRawValue + private String body; + private Throwable error; + + public long getStatus() { + return status; + } + + public void setStatus(long status) { + this.status = status; + } + + public Map> getHeaders() { + return headers; + } + + public void setHeaders(Map> headers) { + this.headers = headers; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public Throwable getError() { + return error; + } + + public void setError(Throwable error) { + this.error = error; + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000000..6f5b0bb2b5 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,9 @@ +name: Ftl Java Runtime +#description: Do something useful. +metadata: +# keywords: +# - ftl-java-runtime +# guide: ... # To create and publish this guide, see https://github.com/quarkiverse/quarkiverse/wiki#documenting-your-extension +# categories: +# - "miscellaneous" +# status: "preview" diff --git a/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource new file mode 100644 index 0000000000..28ef804d0b --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource @@ -0,0 +1 @@ +xyz.block.ftl.runtime.FTLConfigSource \ No newline at end of file diff --git a/java-runtime/ftl-runtime/test-framework/pom.xml b/java-runtime/ftl-runtime/test-framework/pom.xml new file mode 100644 index 0000000000..c66028219f --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + + xyz.block + ftl-java-runtime-parent + 1.0.0-SNAPSHOT + + ftl-java-test-framework + Ftl Java Runtime - Test Framework + + + + + xyz.block + ftl-java-runtime + + + io.quarkus + quarkus-junit5 + compile + + + io.rest-assured + rest-assured + test + + + + + diff --git a/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/FTLManaged.java b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/FTLManaged.java new file mode 100644 index 0000000000..bfcf6f7b98 --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/FTLManaged.java @@ -0,0 +1,8 @@ +package xyz.block.ftl.java.test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface FTLManaged { +} diff --git a/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/TestFTL.java b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/TestFTL.java new file mode 100644 index 0000000000..0259f26c9a --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/TestFTL.java @@ -0,0 +1,16 @@ +package xyz.block.ftl.java.test; + +public class TestFTL { + + public static TestFTL FTL = new TestFTL(); + + public static TestFTL ftl() { + return FTL; + } + + public TestFTL setSecret(String secret, byte[] value) { + + return this; + } + +} diff --git a/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestResource.java b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestResource.java new file mode 100644 index 0000000000..f7fb23accf --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestResource.java @@ -0,0 +1,27 @@ +package xyz.block.ftl.java.test.internal; + +import java.util.Map; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class FTLTestResource implements QuarkusTestResourceLifecycleManager { + + FTLTestServer server; + + @Override + public Map start() { + server = new FTLTestServer(); + server.start(); + return Map.of("ftl.endpoint", "http://127.0.0.1:" + server.getPort()); + } + + @Override + public void stop() { + server.stop(); + } + + @Override + public void inject(TestInjector testInjector) { + + } +} diff --git a/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestServer.java b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestServer.java new file mode 100644 index 0000000000..163a3ccad6 --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/FTLTestServer.java @@ -0,0 +1,33 @@ +package xyz.block.ftl.java.test.internal; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import io.grpc.Server; +import io.grpc.netty.NettyServerBuilder; + +public class FTLTestServer { + + Server grpcServer; + + public void start() { + + var addr = new InetSocketAddress("127.0.0.1", 0); + grpcServer = NettyServerBuilder.forAddress(addr) + .addService(new TestVerbServer()) + .build(); + try { + grpcServer.start(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public int getPort() { + return grpcServer.getPort(); + } + + public void stop() { + grpcServer.shutdown(); + } +} diff --git a/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/TestVerbServer.java b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/TestVerbServer.java new file mode 100644 index 0000000000..bd46c97b0c --- /dev/null +++ b/java-runtime/ftl-runtime/test-framework/src/main/java/xyz/block/ftl/java/test/internal/TestVerbServer.java @@ -0,0 +1,109 @@ +package xyz.block.ftl.java.test.internal; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.ByteString; + +import io.grpc.ManagedChannelBuilder; +import io.grpc.stub.StreamObserver; +import io.quarkus.arc.Arc; +import xyz.block.ftl.v1.AcquireLeaseRequest; +import xyz.block.ftl.v1.AcquireLeaseResponse; +import xyz.block.ftl.v1.CallRequest; +import xyz.block.ftl.v1.CallResponse; +import xyz.block.ftl.v1.ModuleContextRequest; +import xyz.block.ftl.v1.ModuleContextResponse; +import xyz.block.ftl.v1.PingRequest; +import xyz.block.ftl.v1.PingResponse; +import xyz.block.ftl.v1.PublishEventRequest; +import xyz.block.ftl.v1.PublishEventResponse; +import xyz.block.ftl.v1.SendFSMEventRequest; +import xyz.block.ftl.v1.SendFSMEventResponse; +import xyz.block.ftl.v1.VerbServiceGrpc; + +public class TestVerbServer extends VerbServiceGrpc.VerbServiceImplBase { + + final VerbServiceGrpc.VerbServiceStub verbService; + + /** + * TODO: this is so hacked up + */ + static final Map> fakeVerbs = new HashMap<>(); + + public TestVerbServer() { + var channelBuilder = ManagedChannelBuilder.forAddress("127.0.0.1", 8081); + channelBuilder.usePlaintext(); + var channel = channelBuilder.build(); + verbService = VerbServiceGrpc.newStub(channel); + } + + @Override + public void call(CallRequest request, StreamObserver responseObserver) { + Key key = new Key(request.getVerb().getModule(), request.getVerb().getName()); + if (fakeVerbs.containsKey(key)) { + //TODO: YUCK YUCK YUCK + //This all needs a refactor + ObjectMapper mapper = Arc.container().instance(ObjectMapper.class).get(); + + Function function = fakeVerbs.get(key); + Class type = null; + for (var m : function.getClass().getMethods()) { + if (m.getName().equals("apply") && m.getParameterCount() == 1) { + type = m.getParameterTypes()[0]; + if (type != Object.class) { + break; + } + } + } + try { + var result = function.apply(mapper.readerFor(type).readValue(request.getBody().newInput())); + responseObserver.onNext( + CallResponse.newBuilder().setBody(ByteString.copyFrom(mapper.writeValueAsBytes(result))).build()); + responseObserver.onCompleted(); + } catch (IOException e) { + responseObserver.onError(e); + } + return; + } + verbService.call(request, responseObserver); + } + + @Override + public void publishEvent(PublishEventRequest request, StreamObserver responseObserver) { + super.publishEvent(request, responseObserver); + } + + @Override + public void sendFSMEvent(SendFSMEventRequest request, StreamObserver responseObserver) { + super.sendFSMEvent(request, responseObserver); + } + + @Override + public StreamObserver acquireLease(StreamObserver responseObserver) { + return super.acquireLease(responseObserver); + } + + @Override + public void getModuleContext(ModuleContextRequest request, StreamObserver responseObserver) { + responseObserver.onNext(ModuleContextResponse.newBuilder().setModule("test") + .putConfigs("test", ByteString.copyFrom("test", StandardCharsets.UTF_8)).build()); + } + + @Override + public void ping(PingRequest request, StreamObserver responseObserver) { + responseObserver.onNext(PingResponse.newBuilder().build()); + responseObserver.onCompleted(); + } + + public static void registerFakeVerb(String module, String verb, Function verbFunction) { + fakeVerbs.put(new Key(module, verb), verbFunction); + } + + record Key(String module, String verb) { + } +} diff --git a/java-runtime/ftl-runtime/test-framework/src/main/resources/application.properties b/java-runtime/ftl-runtime/test-framework/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 From c5b3687c6827efd718f9e1485cb73436b4e0c64d Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Tue, 13 Aug 2024 12:51:44 +1000 Subject: [PATCH 22/35] feat: java lease support (#2333) Tests will come later as part of a larger testing effort --- .../block/ftl/deployment/FtlProcessor.java | 9 +++- .../main/java/xyz/block/ftl/LeaseClient.java | 11 ++++ .../xyz/block/ftl/LeaseFailedException.java | 26 ++++++++++ .../xyz/block/ftl/runtime/FTLController.java | 52 ++++++++++++++++++- .../xyz/block/ftl/runtime/FTLRecorder.java | 34 ++++++++++++ 5 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseClient.java create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseFailedException.java diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java index 529d4ed36e..a0737d5e8b 100644 --- a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java @@ -66,6 +66,7 @@ import xyz.block.ftl.Cron; import xyz.block.ftl.Export; import xyz.block.ftl.GeneratedRef; +import xyz.block.ftl.LeaseClient; import xyz.block.ftl.Retry; import xyz.block.ftl.Secret; import xyz.block.ftl.Subscription; @@ -120,6 +121,7 @@ class FtlProcessor { public static final DotName CONFIG = DotName.createSimple(Config.class); public static final DotName OFFSET_DATE_TIME = DotName.createSimple(OffsetDateTime.class.getName()); public static final DotName GENERATED_REF = DotName.createSimple(GeneratedRef.class); + public static final DotName LEASE_CLIENT = DotName.createSimple(LeaseClient.class); @BuildStep ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem) { @@ -187,12 +189,12 @@ public ParameterExtractor handleCustomParameter(org.jboss.jandex.Type type, return new VerbRegistry.ConfigSupplier(name, paramType); } else if (topics.getTopics().containsKey(type.name())) { var topic = topics.getTopics().get(type.name()); - Class paramType = loadClass(type); return recorder.topicParamExtractor(topic.generatedProducer()); } else if (verbClients.getVerbClients().containsKey(type.name())) { var client = verbClients.getVerbClients().get(type.name()); - Class paramType = loadClass(type); return recorder.verbParamExtractor(client.generatedClient()); + } else if (LEASE_CLIENT.equals(type.name())) { + return recorder.leaseClientExtractor(); } return null; } catch (ClassNotFoundException e) { @@ -451,6 +453,9 @@ private void handleVerbMethod(ExtractionContext context, MethodInfo method, Stri parameterTypes.add(paramType); paramMappers.add(context.recorder().verbClientSupplier(client.generatedClient())); callsMetadata.addCalls(Ref.newBuilder().setName(client.name()).setModule(client.module()).build()); + } else if (LEASE_CLIENT.equals(param.type().name())) { + parameterTypes.add(LeaseClient.class); + paramMappers.add(context.recorder().leaseClientSupplier()); } else if (bodyType != BodyType.DISALLOWED && bodyParamType == null) { bodyParamType = param.type(); Class paramType = loadClass(param.type()); diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseClient.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseClient.java new file mode 100644 index 0000000000..4f5cc51242 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseClient.java @@ -0,0 +1,11 @@ +package xyz.block.ftl; + +import java.time.Duration; + +/** + * Client that can be used to acquire a FTL lease. If the lease cannot be acquired a {@link LeaseFailedException} is thrown. + */ +public interface LeaseClient { + + void acquireLease(Duration duration, String... keys) throws LeaseFailedException; +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseFailedException.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseFailedException.java new file mode 100644 index 0000000000..0a9bb45ef5 --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/LeaseFailedException.java @@ -0,0 +1,26 @@ +package xyz.block.ftl; + +/** + * Checked exception that is thrown when a lease cannot be acquired + */ +public class LeaseFailedException extends Exception { + + public LeaseFailedException() { + } + + public LeaseFailedException(String message) { + super(message); + } + + public LeaseFailedException(String message, Throwable cause) { + super(message, cause); + } + + public LeaseFailedException(Throwable cause) { + super(cause); + } + + public LeaseFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java index 28b65e3cd9..25eb62fb65 100644 --- a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java @@ -1,8 +1,12 @@ package xyz.block.ftl.runtime; import java.net.URI; +import java.time.Duration; +import java.util.Arrays; +import java.util.Deque; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.LinkedBlockingDeque; import jakarta.inject.Singleton; @@ -14,6 +18,10 @@ import io.grpc.ManagedChannelBuilder; import io.grpc.stub.StreamObserver; import io.quarkus.runtime.Startup; +import xyz.block.ftl.LeaseClient; +import xyz.block.ftl.LeaseFailedException; +import xyz.block.ftl.v1.AcquireLeaseRequest; +import xyz.block.ftl.v1.AcquireLeaseResponse; import xyz.block.ftl.v1.CallRequest; import xyz.block.ftl.v1.CallResponse; import xyz.block.ftl.v1.ModuleContextRequest; @@ -25,9 +33,11 @@ @Singleton @Startup -public class FTLController { +public class FTLController implements LeaseClient { private static final Logger log = Logger.getLogger(FTLController.class); final String moduleName; + private StreamObserver leaseClient; + private final Deque> leaseWaiters = new LinkedBlockingDeque<>(); private Throwable currentError; private volatile ModuleContextResponse moduleContextResponse; @@ -76,7 +86,29 @@ public FTLController(@ConfigProperty(name = "ftl.endpoint", defaultValue = "http var channel = channelBuilder.build(); verbService = VerbServiceGrpc.newStub(channel); verbService.getModuleContext(ModuleContextRequest.newBuilder().setModule(moduleName).build(), moduleObserver); + synchronized (this) { + this.leaseClient = verbService.acquireLease(new StreamObserver() { + @Override + public void onNext(AcquireLeaseResponse value) { + leaseWaiters.pop().complete(null); + } + + @Override + public void onError(Throwable t) { + leaseWaiters.pop().completeExceptionally(t); + } + @Override + public void onCompleted() { + synchronized (FTLController.this) { + while (!leaseWaiters.isEmpty()) { + leaseWaiters.pop().completeExceptionally(new RuntimeException("connection closed")); + } + leaseClient = verbService.acquireLease(this); + } + } + }); + } } public byte[] getSecret(String secretName) { @@ -97,6 +129,7 @@ public byte[] getConfig(String secretName) { public byte[] callVerb(String name, String module, byte[] payload) { CompletableFuture cf = new CompletableFuture<>(); + verbService.call(CallRequest.newBuilder().setVerb(Ref.newBuilder().setModule(module).setName(name)) .setBody(ByteString.copyFrom(payload)).build(), new StreamObserver<>() { @@ -154,6 +187,23 @@ public void onCompleted() { } } + public void acquireLease(Duration duration, String... keys) throws LeaseFailedException { + CompletableFuture cf = new CompletableFuture<>(); + synchronized (this) { + leaseWaiters.push(cf); + leaseClient.onNext(AcquireLeaseRequest.newBuilder().setModule(moduleName) + .addAllKey(Arrays.asList(keys)) + .setTtl(com.google.protobuf.Duration.newBuilder() + .setSeconds(duration.toSeconds())) + .build()); + } + try { + cf.get(); + } catch (Exception e) { + throw new LeaseFailedException(e); + } + } + private ModuleContextResponse getModuleContext() { var moduleContext = moduleContextResponse; if (moduleContext != null) { diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java index 6b839518c1..ed9b901d5f 100644 --- a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java @@ -12,6 +12,7 @@ import io.quarkus.arc.Arc; import io.quarkus.runtime.annotations.Recorder; +import xyz.block.ftl.LeaseClient; import xyz.block.ftl.v1.CallRequest; @Recorder @@ -71,6 +72,20 @@ public Object apply(ObjectMapper mapper, CallRequest callRequest) { } } + public BiFunction leaseClientSupplier() { + return new BiFunction() { + volatile LeaseClient leaseClient; + + @Override + public Object apply(ObjectMapper mapper, CallRequest callRequest) { + if (leaseClient == null) { + leaseClient = Arc.container().instance(LeaseClient.class).get(); + } + return leaseClient; + } + }; + } + public ParameterExtractor topicParamExtractor(String className) { try { @@ -107,4 +122,23 @@ public Object extractParameter(ResteasyReactiveRequestContext context) { throw new RuntimeException(e); } } + + public ParameterExtractor leaseClientExtractor() { + try { + return new ParameterExtractor() { + + volatile LeaseClient leaseClient; + + @Override + public Object extractParameter(ResteasyReactiveRequestContext context) { + if (leaseClient == null) { + leaseClient = Arc.container().instance(LeaseClient.class).get(); + } + return leaseClient; + } + }; + } catch (Exception e) { + throw new RuntimeException(e); + } + } } From 9e82265b1765989ff9cc87b5dfa2165aea973b26 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Tue, 13 Aug 2024 14:12:09 +1000 Subject: [PATCH 23/35] chore: remove old testdata (#2335) Co-authored-by: github-actions[bot] --- cmd/lint-commit-or-rollback/go.mod | 11 +-- cmd/lint-commit-or-rollback/go.sum | 6 -- cmd/lint-commit-or-rollback/main_test.go | 25 ------- cmd/lint-commit-or-rollback/testdata/go.mod | 7 -- cmd/lint-commit-or-rollback/testdata/go.sum | 34 ---------- cmd/lint-commit-or-rollback/testdata/main.go | 70 -------------------- 6 files changed, 2 insertions(+), 151 deletions(-) delete mode 100644 cmd/lint-commit-or-rollback/main_test.go delete mode 100644 cmd/lint-commit-or-rollback/testdata/go.mod delete mode 100644 cmd/lint-commit-or-rollback/testdata/go.sum delete mode 100644 cmd/lint-commit-or-rollback/testdata/main.go diff --git a/cmd/lint-commit-or-rollback/go.mod b/cmd/lint-commit-or-rollback/go.mod index c000a843ce..351e6edef6 100644 --- a/cmd/lint-commit-or-rollback/go.mod +++ b/cmd/lint-commit-or-rollback/go.mod @@ -4,13 +4,6 @@ go 1.22.0 require golang.org/x/tools v0.24.0 -require ( - github.com/alecthomas/repr v0.4.0 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect - golang.org/x/sync v0.8.0 // indirect -) +require golang.org/x/sync v0.8.0 // indirect -require ( - github.com/alecthomas/assert/v2 v2.10.0 - golang.org/x/mod v0.20.0 // indirect -) +require golang.org/x/mod v0.20.0 // indirect diff --git a/cmd/lint-commit-or-rollback/go.sum b/cmd/lint-commit-or-rollback/go.sum index 23f6abe190..5b7f1f0a60 100644 --- a/cmd/lint-commit-or-rollback/go.sum +++ b/cmd/lint-commit-or-rollback/go.sum @@ -1,11 +1,5 @@ -github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= -github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= -github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= diff --git a/cmd/lint-commit-or-rollback/main_test.go b/cmd/lint-commit-or-rollback/main_test.go deleted file mode 100644 index 430af58672..0000000000 --- a/cmd/lint-commit-or-rollback/main_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "os" - "os/exec" - "strings" - "testing" - - "github.com/alecthomas/assert/v2" -) - -func TestLinter(t *testing.T) { - pwd, err := os.Getwd() - assert.NoError(t, err) - cmd := exec.Command("lint-commit-or-rollback", ".") - cmd.Dir = "testdata" - output, err := cmd.CombinedOutput() - assert.Error(t, err) - expected := ` -` + pwd + `/testdata/main.go:35:29: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:29:6 has no named return parameters -` + pwd + `/testdata/main.go:44:28: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:28:1 has no named return parameters -` + pwd + `/testdata/main.go:55:29: defer tx.CommitOrRollback(&err) should be deferred with a reference to a named error return parameter, but the function at /Users/alec/dev/pfi/cmd/lint-commit-or-rollback/testdata/main.go:49:6 has no named return parameters - ` - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(output))) -} diff --git a/cmd/lint-commit-or-rollback/testdata/go.mod b/cmd/lint-commit-or-rollback/testdata/go.mod deleted file mode 100644 index 1e35d08e48..0000000000 --- a/cmd/lint-commit-or-rollback/testdata/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module main - -go 1.22.2 - -replace pfi/backend => ../../../backend - -require pfi/backend v0.0.0-00010101000000-000000000000 diff --git a/cmd/lint-commit-or-rollback/testdata/go.sum b/cmd/lint-commit-or-rollback/testdata/go.sum deleted file mode 100644 index 07c3ecb203..0000000000 --- a/cmd/lint-commit-or-rollback/testdata/go.sum +++ /dev/null @@ -1,34 +0,0 @@ -github.com/alecthomas/assert/v2 v2.5.0 h1:OJKYg53BQx06/bMRBSPDCO49CbCDNiUQXwdoNrt6x5w= -github.com/alecthomas/assert/v2 v2.5.0/go.mod h1:fw5suVxB+wfYJ3291t0hRTqtGzFYdSwstnRQdaQx2DM= -github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8= -github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= -modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= -modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= -modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/cmd/lint-commit-or-rollback/testdata/main.go b/cmd/lint-commit-or-rollback/testdata/main.go deleted file mode 100644 index 5d87b35f00..0000000000 --- a/cmd/lint-commit-or-rollback/testdata/main.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "context" - "database/sql" - - libdal "pfi/backend/libs/dal" -) - -type Tx struct { - *libdal.Tx[Tx] - *DAL -} - -// DAL is the data access layer for the IDV module. -type DAL struct { - db libdal.Conn - *libdal.DAL[Tx] -} - -// NewDAL creates a new Data Access Layer instance. -func NewDAL(conn *sql.DB) *DAL { - return &DAL{db: conn, DAL: libdal.New(conn, func(tx *sql.Tx, t *libdal.Tx[Tx]) *Tx { - return &Tx{DAL: &DAL{db: tx, DAL: t.DAL}, Tx: t} - })} -} - -func failure() error { - _ = func() error { - dal := DAL{} - tx, err := dal.Begin(context.Background()) - if err != nil { - return err - } - defer tx.CommitOrRollback(&err) // Should error - return nil - } - - dal := DAL{} - tx, err := dal.Begin(context.Background()) - if err != nil { - return err - } - defer tx.CommitOrRollback(&err) // Should error - return nil -} - -func success() (err error) { - _ = func() error { - dal := DAL{} - tx, err := dal.Begin(context.Background()) - if err != nil { - return err - } - defer tx.CommitOrRollback(&err) // Should error - return nil - } - dal := DAL{} - tx, err := dal.Begin(context.Background()) - if err != nil { - return err - } - defer tx.CommitOrRollback(&err) // Should NOT error - return nil -} - -func main() { - _ = failure() - _ = success() -} From 907731e5a5b3d34468399a021eb1f379198bf338 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Tue, 13 Aug 2024 21:01:33 +1000 Subject: [PATCH 24/35] feat: initial java <-> go integration test (#2339) Initial PR that tests simple interop. This will be expanded to cover as many different types and features as possible. --- go-runtime/compile/build.go | 5 +- integration/harness.go | 23 ++- .../ftl/deployment/FTLCodeGenerator.java | 2 +- .../block/ftl/deployment/FtlProcessor.java | 10 +- .../xyz/block/ftl/runtime/FTLRecorder.java | 5 +- .../ftl/runtime/JsonSerializationConfig.java | 18 +++ .../xyz/block/ftl/runtime/VerbRegistry.java | 23 ++- java-runtime/java_integration_test.go | 58 +++++++ java-runtime/testdata/go/gomodule/ftl.toml | 5 + java-runtime/testdata/go/gomodule/go.mod | 5 + java-runtime/testdata/go/gomodule/go.sum | 0 java-runtime/testdata/go/gomodule/server.go | 38 +++++ java-runtime/testdata/go/javamodule/ftl.toml | 2 + java-runtime/testdata/go/javamodule/pom.xml | 141 ++++++++++++++++++ .../xyz/block/ftl/java/test/TestInvokeGo.java | 45 ++++++ 15 files changed, 364 insertions(+), 16 deletions(-) create mode 100644 java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/JsonSerializationConfig.java create mode 100644 java-runtime/java_integration_test.go create mode 100644 java-runtime/testdata/go/gomodule/ftl.toml create mode 100644 java-runtime/testdata/go/gomodule/go.mod create mode 100644 java-runtime/testdata/go/gomodule/go.sum create mode 100644 java-runtime/testdata/go/gomodule/server.go create mode 100644 java-runtime/testdata/go/javamodule/ftl.toml create mode 100644 java-runtime/testdata/go/javamodule/pom.xml create mode 100644 java-runtime/testdata/go/javamodule/src/main/java/xyz/block/ftl/java/test/TestInvokeGo.java diff --git a/go-runtime/compile/build.go b/go-runtime/compile/build.go index 638a89b4f5..d599035aaf 100644 --- a/go-runtime/compile/build.go +++ b/go-runtime/compile/build.go @@ -289,7 +289,7 @@ func GenerateStubsForModules(ctx context.Context, projectRoot string, moduleConf var moduleConfig *moduleconfig.ModuleConfig for _, mc := range moduleConfigs { mcCopy := mc - if mc.Module == module.Name { + if mc.Module == module.Name && mc.Language == "go" { moduleConfig = &mcCopy break } @@ -362,6 +362,9 @@ func SyncGeneratedStubReferences(ctx context.Context, projectRootDir string, stu } sharedModulesPaths = append(sharedModulesPaths, filepath.Join(projectRootDir, buildDirName, "go", "modules", mod)) } + if moduleConfig.Language != "go" { + continue + } _, goModVersion, err := updateGoModule(filepath.Join(moduleConfig.Dir, "go.mod")) if err != nil { diff --git a/integration/harness.go b/integration/harness.go index da11527ae7..aae96f7f13 100644 --- a/integration/harness.go +++ b/integration/harness.go @@ -51,7 +51,18 @@ var buildOnce sync.Once // "database/ftl-project.toml" would set FTL_CONFIG to // "integration/testdata/go/database/ftl-project.toml"). func Run(t *testing.T, ftlConfigPath string, actions ...Action) { - run(t, ftlConfigPath, true, actions...) + run(t, ftlConfigPath, true, false, actions...) +} + +// RunWithJava runs an integration test after building the Java runtime. +// ftlConfigPath: if FTL_CONFIG should be set for this test, then pass in the relative +// +// path based on ./testdata/go/ where "." denotes the directory containing the +// integration test (e.g. for "integration/harness_test.go" supplying +// "database/ftl-project.toml" would set FTL_CONFIG to +// "integration/testdata/go/database/ftl-project.toml"). +func RunWithJava(t *testing.T, ftlConfigPath string, actions ...Action) { + run(t, ftlConfigPath, true, true, actions...) } // RunWithoutController runs an integration test without starting the controller. @@ -62,7 +73,7 @@ func Run(t *testing.T, ftlConfigPath string, actions ...Action) { // "database/ftl-project.toml" would set FTL_CONFIG to // "integration/testdata/go/database/ftl-project.toml"). func RunWithoutController(t *testing.T, ftlConfigPath string, actions ...Action) { - run(t, ftlConfigPath, false, actions...) + run(t, ftlConfigPath, false, false, actions...) } func RunWithEncryption(t *testing.T, ftlConfigPath string, actions ...Action) { @@ -72,10 +83,10 @@ func RunWithEncryption(t *testing.T, ftlConfigPath string, actions ...Action) { t.Setenv("FTL_LOG_ENCRYPTION_KEY", logKey) t.Setenv("FTL_ASYNC_ENCRYPTION_KEY", asyncKey) - run(t, ftlConfigPath, true, actions...) + run(t, ftlConfigPath, true, false, actions...) } -func run(t *testing.T, ftlConfigPath string, startController bool, actions ...Action) { +func run(t *testing.T, ftlConfigPath string, startController bool, requireJava bool, actions ...Action) { tmpDir := t.TempDir() cwd, err := os.Getwd() @@ -116,6 +127,10 @@ func run(t *testing.T, ftlConfigPath string, startController bool, actions ...Ac Infof("Building ftl") err = ftlexec.Command(ctx, log.Debug, rootDir, "just", "build", "ftl").RunBuffered(ctx) assert.NoError(t, err) + if requireJava { + err = ftlexec.Command(ctx, log.Debug, rootDir, "just", "build-java").RunBuffered(ctx) + assert.NoError(t, err) + } }) verbs := rpc.Dial(ftlv1connect.NewVerbServiceClient, "http://localhost:8892", log.Debug) diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java index 4e3c4f7b59..dce8144fed 100644 --- a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FTLCodeGenerator.java @@ -113,7 +113,7 @@ public boolean trigger(CodeGenContext context) throws CodeGenException { .build()) .addModifiers(Modifier.PUBLIC); if (verb.getRequest().hasUnit() && verb.getResponse().hasUnit()) { - typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientEmpty.class))); + typeBuilder.addSuperinterface(ClassName.get(VerbClientEmpty.class)); } else if (verb.getRequest().hasUnit()) { typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientSource.class), toJavaTypeName(verb.getResponse(), typeAliasMap))); diff --git a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java index a0737d5e8b..538ecd739d 100644 --- a/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java +++ b/java-runtime/ftl-runtime/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java @@ -75,6 +75,7 @@ import xyz.block.ftl.runtime.FTLController; import xyz.block.ftl.runtime.FTLHttpHandler; import xyz.block.ftl.runtime.FTLRecorder; +import xyz.block.ftl.runtime.JsonSerializationConfig; import xyz.block.ftl.runtime.TopicHelper; import xyz.block.ftl.runtime.VerbClientHelper; import xyz.block.ftl.runtime.VerbHandler; @@ -149,8 +150,9 @@ BindableServiceBuildItem verbService() { @BuildStep AdditionalBeanBuildItem beans() { return AdditionalBeanBuildItem.builder() - .addBeanClasses(VerbHandler.class, VerbRegistry.class, FTLHttpHandler.class, FTLController.class, - TopicHelper.class, VerbClientHelper.class) + .addBeanClasses(VerbHandler.class, + VerbRegistry.class, FTLHttpHandler.class, FTLController.class, + TopicHelper.class, VerbClientHelper.class, JsonSerializationConfig.class) .setUnremovable().build(); } @@ -477,8 +479,10 @@ private void handleVerbMethod(ExtractionContext context, MethodInfo method, Stri verbBuilder.addMetadata(Metadata.newBuilder().setCalls(callsMetadata)); } + //TODO: we need better handling around Optional context.recorder.registerVerb(context.moduleName(), verbName, method.name(), parameterTypes, - Class.forName(className, false, Thread.currentThread().getContextClassLoader()), paramMappers); + Class.forName(className, false, Thread.currentThread().getContextClassLoader()), paramMappers, + method.returnType() == VoidType.VOID); verbBuilder .setName(verbName) .setExport(exported) diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java index ed9b901d5f..5ee6413076 100644 --- a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java @@ -21,13 +21,14 @@ public class FTLRecorder { public static final String X_FTL_VERB = "X-ftl-verb"; public void registerVerb(String module, String verbName, String methodName, List> parameterTypes, - Class verbHandlerClass, List> paramMappers) { + Class verbHandlerClass, List> paramMappers, + boolean allowNullReturn) { //TODO: this sucks try { var method = verbHandlerClass.getDeclaredMethod(methodName, parameterTypes.toArray(new Class[0])); var handlerInstance = Arc.container().instance(verbHandlerClass); Arc.container().instance(VerbRegistry.class).get().register(module, verbName, handlerInstance, method, - paramMappers); + paramMappers, allowNullReturn); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/JsonSerializationConfig.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/JsonSerializationConfig.java new file mode 100644 index 0000000000..b17d9f94fd --- /dev/null +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/JsonSerializationConfig.java @@ -0,0 +1,18 @@ +package xyz.block.ftl.runtime; + +import jakarta.enterprise.event.Observes; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +import io.quarkus.runtime.StartupEvent; + +/** + * This class configures the FTL serialization + */ +public class JsonSerializationConfig { + + void startup(@Observes StartupEvent event, ObjectMapper mapper) { + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + } +} diff --git a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java index a0202690b4..42166c0719 100644 --- a/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java +++ b/java-runtime/ftl-runtime/runtime/src/main/java/xyz/block/ftl/runtime/VerbRegistry.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -35,8 +36,8 @@ public VerbRegistry(ObjectMapper mapper) { } public void register(String module, String name, InstanceHandle verbHandlerClass, Method method, - List> paramMappers) { - verbs.put(new Key(module, name), new AnnotatedEndpointHandler(verbHandlerClass, method, paramMappers)); + List> paramMappers, boolean allowNullReturn) { + verbs.put(new Key(module, name), new AnnotatedEndpointHandler(verbHandlerClass, method, paramMappers, allowNullReturn)); } public void register(String module, String name, VerbInvoker verbInvoker) { @@ -60,12 +61,14 @@ private class AnnotatedEndpointHandler implements VerbInvoker { final InstanceHandle verbHandlerClass; final Method method; final List> parameterSuppliers; + final boolean allowNull; private AnnotatedEndpointHandler(InstanceHandle verbHandlerClass, Method method, - List> parameterSuppliers) { + List> parameterSuppliers, boolean allowNull) { this.verbHandlerClass = verbHandlerClass; this.method = method; this.parameterSuppliers = parameterSuppliers; + this.allowNull = allowNull; } public CallResponse handle(CallRequest in) { @@ -76,8 +79,18 @@ public CallResponse handle(CallRequest in) { } Object ret; ret = method.invoke(verbHandlerClass.get(), params); - var mappedResponse = mapper.writer().writeValueAsBytes(ret); - return CallResponse.newBuilder().setBody(ByteString.copyFrom(mappedResponse)).build(); + if (ret == null) { + if (allowNull) { + return CallResponse.newBuilder().setBody(ByteString.copyFrom("{}", StandardCharsets.UTF_8)).build(); + } else { + return CallResponse.newBuilder().setError( + CallResponse.Error.newBuilder().setMessage("Verb returned an unexpected null response").build()) + .build(); + } + } else { + var mappedResponse = mapper.writer().writeValueAsBytes(ret); + return CallResponse.newBuilder().setBody(ByteString.copyFrom(mappedResponse)).build(); + } } catch (Exception e) { log.errorf(e, "Failed to invoke verb %s.%s", in.getVerb().getModule(), in.getVerb().getName()); return CallResponse.newBuilder().setError(CallResponse.Error.newBuilder().setMessage(e.getMessage()).build()) diff --git a/java-runtime/java_integration_test.go b/java-runtime/java_integration_test.go new file mode 100644 index 0000000000..d64f14854a --- /dev/null +++ b/java-runtime/java_integration_test.go @@ -0,0 +1,58 @@ +//go:build integration + +package ftl_test + +import ( + "testing" + "time" + + "github.com/alecthomas/assert/v2" + + in "github.com/TBD54566975/ftl/integration" + + "github.com/alecthomas/repr" +) + +func TestJavaToGoCall(t *testing.T) { + in.RunWithJava(t, "", + in.CopyModule("gomodule"), + in.CopyDir("javamodule", "javamodule"), + in.Deploy("gomodule"), + in.Deploy("javamodule"), + in.Call("javamodule", "timeVerb", in.Obj{}, func(t testing.TB, response in.Obj) { + message, ok := response["time"].(string) + assert.True(t, ok, "time is not a string: %s", repr.String(response)) + result, err := time.Parse(time.RFC3339, message) + assert.NoError(t, err, "time is not a valid RFC3339 time: %s", message) + assert.True(t, result.After(time.Now().Add(-time.Minute)), "time is not recent: %s", message) + }), + // We call both the go and pass through Java versions + // To make sure the response is the same + in.Call("gomodule", "emptyVerb", in.Obj{}, func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), + in.Call("javamodule", "emptyVerb", in.Obj{}, func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), + in.Call("gomodule", "sinkVerb", "ignored", func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), + in.Call("javamodule", "sinkVerb", "ignored", func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), + in.Call("gomodule", "sourceVerb", in.Obj{}, func(t testing.TB, response string) { + assert.Equal(t, "Source Verb", response, "expecting empty response, got %s", response) + }), + in.Call("javamodule", "sourceVerb", in.Obj{}, func(t testing.TB, response string) { + assert.Equal(t, "Source Verb", response, "expecting empty response, got %s", response) + }), + in.Fail( + in.Call("gomodule", "errorEmptyVerb", in.Obj{}, func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), "verb failed"), + in.Fail( + in.Call("gomodule", "errorEmptyVerb", in.Obj{}, func(t testing.TB, response in.Obj) { + assert.Equal(t, map[string]any{}, response, "expecting empty response, got %s", repr.String(response)) + }), "verb failed"), + ) +} diff --git a/java-runtime/testdata/go/gomodule/ftl.toml b/java-runtime/testdata/go/gomodule/ftl.toml new file mode 100644 index 0000000000..5becff80a9 --- /dev/null +++ b/java-runtime/testdata/go/gomodule/ftl.toml @@ -0,0 +1,5 @@ +module = "gomodule" +language = "go" + +[go.replace] +"github.com/TBD54566975/ftl" = "../.." diff --git a/java-runtime/testdata/go/gomodule/go.mod b/java-runtime/testdata/go/gomodule/go.mod new file mode 100644 index 0000000000..3773c01c5d --- /dev/null +++ b/java-runtime/testdata/go/gomodule/go.mod @@ -0,0 +1,5 @@ +module ftl/gomodule + +go 1.22.2 + +replace github.com/TBD54566975/ftl => ./../../../.. diff --git a/java-runtime/testdata/go/gomodule/go.sum b/java-runtime/testdata/go/gomodule/go.sum new file mode 100644 index 0000000000..e69de29bb2 diff --git a/java-runtime/testdata/go/gomodule/server.go b/java-runtime/testdata/go/gomodule/server.go new file mode 100644 index 0000000000..65d6d4b0df --- /dev/null +++ b/java-runtime/testdata/go/gomodule/server.go @@ -0,0 +1,38 @@ +package gomodule + +import ( + "context" + "fmt" + "time" +) + +type TimeRequest struct { +} +type TimeResponse struct { + Time time.Time +} + +//ftl:verb export +func SourceVerb(ctx context.Context) (string, error) { + return "Source Verb", nil +} + +//ftl:verb export +func SinkVerb(ctx context.Context, req string) error { + return nil +} + +//ftl:verb export +func EmptyVerb(ctx context.Context) error { + return nil +} + +//ftl:verb export +func ErrorEmptyVerb(ctx context.Context) error { + return fmt.Errorf("verb failed") +} + +//ftl:verb export +func Time(ctx context.Context, req TimeRequest) (TimeResponse, error) { + return TimeResponse{Time: time.Now()}, nil +} diff --git a/java-runtime/testdata/go/javamodule/ftl.toml b/java-runtime/testdata/go/javamodule/ftl.toml new file mode 100644 index 0000000000..864288fa76 --- /dev/null +++ b/java-runtime/testdata/go/javamodule/ftl.toml @@ -0,0 +1,2 @@ +module = "echoclient" +language = "java" diff --git a/java-runtime/testdata/go/javamodule/pom.xml b/java-runtime/testdata/go/javamodule/pom.xml new file mode 100644 index 0000000000..43d234296e --- /dev/null +++ b/java-runtime/testdata/go/javamodule/pom.xml @@ -0,0 +1,141 @@ + + + 4.0.0 + xyz.block.ftl.examples + javamodule + 1.0.0-SNAPSHOT + + + 1.0-SNAPSHOT + 3.13.0 + 2.0.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.12.3 + true + 3.2.5 + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + + xyz.block + ftl-java-runtime + 1.0.0-SNAPSHOT + + + io.quarkus + quarkus-kotlin + + + io.quarkus + quarkus-jackson + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-junit5 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + io.rest-assured + kotlin-extensions + test + + + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + native-image-agent + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + native + + + native + + + + false + true + + + + diff --git a/java-runtime/testdata/go/javamodule/src/main/java/xyz/block/ftl/java/test/TestInvokeGo.java b/java-runtime/testdata/go/javamodule/src/main/java/xyz/block/ftl/java/test/TestInvokeGo.java new file mode 100644 index 0000000000..da50c7035f --- /dev/null +++ b/java-runtime/testdata/go/javamodule/src/main/java/xyz/block/ftl/java/test/TestInvokeGo.java @@ -0,0 +1,45 @@ +package xyz.block.ftl.java.test; + +import ftl.gomodule.EmptyVerbClient; +import ftl.gomodule.ErrorEmptyVerbClient; +import ftl.gomodule.SinkVerbClient; +import ftl.gomodule.SourceVerbClient; +import ftl.gomodule.TimeClient; +import ftl.gomodule.TimeRequest; +import ftl.gomodule.TimeResponse; +import org.jetbrains.annotations.NotNull; +import xyz.block.ftl.Export; +import xyz.block.ftl.Verb; + +public class TestInvokeGo { + + @Export + @Verb + public void emptyVerb(EmptyVerbClient emptyVerbClient) { + emptyVerbClient.call(); + } + + @Export + @Verb + public void sinkVerb(String input, SinkVerbClient sinkVerbClient) { + sinkVerbClient.call(input); + } + + @Export + @Verb + public String sourceVerb(SourceVerbClient sourceVerbClient) { + return sourceVerbClient.call(); + } + @Export + @Verb + public void errorEmptyVerb(ErrorEmptyVerbClient client) { + client.call(); + } + + @Export + @Verb + public @NotNull TimeResponse timeVerb(TimeClient client) { + return client.call(new TimeRequest()); + } + +} From a5425b16927c90293444eed48fbf0a52d455d374 Mon Sep 17 00:00:00 2001 From: Safeer Jiwan Date: Tue, 13 Aug 2024 09:35:17 -0700 Subject: [PATCH 25/35] fix(topic): require lowerCamel topic names instead of lower_snake (#2329) Breaking change, fixes #2328 Original topic name PR is #1958 --- backend/controller/cronjobs/sql/db.go | 2 +- backend/controller/cronjobs/sql/models.go | 2 +- backend/controller/cronjobs/sql/querier.go | 2 +- backend/controller/cronjobs/sql/queries.sql.go | 2 +- .../controller/pubsub/testdata/go/publisher/publisher.go | 4 ++-- backend/controller/sql/db.go | 2 +- backend/controller/sql/models.go | 2 +- backend/controller/sql/querier.go | 2 +- backend/controller/sql/queries.sql.go | 2 +- common/configuration/sql/db.go | 2 +- common/configuration/sql/models.go | 2 +- common/configuration/sql/querier.go | 2 +- common/configuration/sql/queries.sql.go | 2 +- .../go/modules/{{ .Module.Name }}/external_module.go.tmpl | 2 +- go-runtime/schema/schema_fuzz_test.go | 4 ++-- go-runtime/schema/schema_test.go | 8 ++++---- go-runtime/schema/subscription/analyzer.go | 2 +- go-runtime/schema/testdata/pubsub/pubsub.go | 4 ++-- go-runtime/schema/topic/analyzer.go | 6 +++--- 19 files changed, 27 insertions(+), 27 deletions(-) diff --git a/backend/controller/cronjobs/sql/db.go b/backend/controller/cronjobs/sql/db.go index 8a1e45d051..0e0973111c 100644 --- a/backend/controller/cronjobs/sql/db.go +++ b/backend/controller/cronjobs/sql/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/cronjobs/sql/models.go b/backend/controller/cronjobs/sql/models.go index c5bddc7eb9..5b5c1c76e4 100644 --- a/backend/controller/cronjobs/sql/models.go +++ b/backend/controller/cronjobs/sql/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/cronjobs/sql/querier.go b/backend/controller/cronjobs/sql/querier.go index 319aa22a60..2bfa010982 100644 --- a/backend/controller/cronjobs/sql/querier.go +++ b/backend/controller/cronjobs/sql/querier.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/cronjobs/sql/queries.sql.go b/backend/controller/cronjobs/sql/queries.sql.go index fe741663db..1064924f55 100644 --- a/backend/controller/cronjobs/sql/queries.sql.go +++ b/backend/controller/cronjobs/sql/queries.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 // source: queries.sql package sql diff --git a/backend/controller/pubsub/testdata/go/publisher/publisher.go b/backend/controller/pubsub/testdata/go/publisher/publisher.go index 38af05f989..e74ecdf191 100644 --- a/backend/controller/pubsub/testdata/go/publisher/publisher.go +++ b/backend/controller/pubsub/testdata/go/publisher/publisher.go @@ -9,7 +9,7 @@ import ( ) //ftl:export -var TestTopic = ftl.Topic[PubSubEvent]("test_topic") +var TestTopic = ftl.Topic[PubSubEvent]("testTopic") type PubSubEvent struct { Time time.Time @@ -38,7 +38,7 @@ func PublishOne(ctx context.Context) error { } //ftl:export -var Topic2 = ftl.Topic[PubSubEvent]("topic_2") +var Topic2 = ftl.Topic[PubSubEvent]("topic2") //ftl:verb func PublishOneToTopic2(ctx context.Context) error { diff --git a/backend/controller/sql/db.go b/backend/controller/sql/db.go index 8a1e45d051..0e0973111c 100644 --- a/backend/controller/sql/db.go +++ b/backend/controller/sql/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/sql/models.go b/backend/controller/sql/models.go index c5bddc7eb9..5b5c1c76e4 100644 --- a/backend/controller/sql/models.go +++ b/backend/controller/sql/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/sql/querier.go b/backend/controller/sql/querier.go index f34f4c44e0..42fc740ffe 100644 --- a/backend/controller/sql/querier.go +++ b/backend/controller/sql/querier.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index a9116d5b4c..77ed4654a6 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 // source: queries.sql package sql diff --git a/common/configuration/sql/db.go b/common/configuration/sql/db.go index 8a1e45d051..0e0973111c 100644 --- a/common/configuration/sql/db.go +++ b/common/configuration/sql/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/common/configuration/sql/models.go b/common/configuration/sql/models.go index c5bddc7eb9..5b5c1c76e4 100644 --- a/common/configuration/sql/models.go +++ b/common/configuration/sql/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/common/configuration/sql/querier.go b/common/configuration/sql/querier.go index b3e7b22247..ac45674c28 100644 --- a/common/configuration/sql/querier.go +++ b/common/configuration/sql/querier.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 package sql diff --git a/common/configuration/sql/queries.sql.go b/common/configuration/sql/queries.sql.go index b20dc48fcd..51c86f6116 100644 --- a/common/configuration/sql/queries.sql.go +++ b/common/configuration/sql/queries.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.26.0 +// sqlc v1.27.0 // source: queries.sql package sql diff --git a/go-runtime/compile/external-module-template/.ftl/go/modules/{{ .Module.Name }}/external_module.go.tmpl b/go-runtime/compile/external-module-template/.ftl/go/modules/{{ .Module.Name }}/external_module.go.tmpl index 7288d73a1a..bff5bbb2fa 100644 --- a/go-runtime/compile/external-module-template/.ftl/go/modules/{{ .Module.Name }}/external_module.go.tmpl +++ b/go-runtime/compile/external-module-template/.ftl/go/modules/{{ .Module.Name }}/external_module.go.tmpl @@ -23,7 +23,7 @@ var _ = context.Background // {{- end}} {{- if is "Topic" .}} -var {{.Name|strippedCamel}} = ftl.Topic[{{type $.Module .Event}}]("{{.Name}}") +var {{.Name|title}} = ftl.Topic[{{type $.Module .Event}}]("{{.Name}}") {{- else if and (is "Enum" .) .IsValueEnum}} {{- $enumName := .Name}} //ftl:enum diff --git a/go-runtime/schema/schema_fuzz_test.go b/go-runtime/schema/schema_fuzz_test.go index ff504be410..7283d5aac3 100644 --- a/go-runtime/schema/schema_fuzz_test.go +++ b/go-runtime/schema/schema_fuzz_test.go @@ -192,7 +192,7 @@ func (ExportedVariant) exportedTag() {} var Topic = ftl.Topic[` + symbol + `]("topic") //ftl:export -var ExportedTopic = ftl.Topic[` + symbol + `]("exported_topic") +var ExportedTopic = ftl.Topic[` + symbol + `]("exportedTopic") var _ = ftl.Subscription(Topic, "subscription") @@ -334,7 +334,7 @@ module test { database postgres testDb - export topic exported_topic {{.TypeName}} + export topic exportedTopic {{.TypeName}} topic topic {{.TypeName}} subscription subscription test.topic diff --git a/go-runtime/schema/schema_test.go b/go-runtime/schema/schema_test.go index 6e33bdaa94..48d59a95e6 100644 --- a/go-runtime/schema/schema_test.go +++ b/go-runtime/schema/schema_test.go @@ -434,10 +434,10 @@ func TestExtractModulePubSub(t *testing.T) { actual := schema.Normalise(r.Module) expected := `module pubsub { topic payins pubsub.PayinEvent - // public_broadcast is a topic that broadcasts payin events to the public. + // publicBroadcast is a topic that broadcasts payin events to the public. // out of order with subscription registration to test ordering doesn't matter. - export topic public_broadcast pubsub.PayinEvent - subscription broadcastSubscription pubsub.public_broadcast + export topic publicBroadcast pubsub.PayinEvent + subscription broadcastSubscription pubsub.publicBroadcast subscription paymentProcessing pubsub.payins export data PayinEvent { @@ -469,7 +469,7 @@ func TestExtractModuleSubscriber(t *testing.T) { assert.Equal(t, nil, r.Errors, "expected no schema errors") actual := schema.Normalise(r.Module) expected := `module subscriber { - subscription subscriptionToExternalTopic pubsub.public_broadcast + subscription subscriptionToExternalTopic pubsub.publicBroadcast verb consumesSubscriptionFromExternalTopic(pubsub.PayinEvent) Unit +subscribe subscriptionToExternalTopic diff --git a/go-runtime/schema/subscription/analyzer.go b/go-runtime/schema/subscription/analyzer.go index ec5c4617e0..d4c4472be3 100644 --- a/go-runtime/schema/subscription/analyzer.go +++ b/go-runtime/schema/subscription/analyzer.go @@ -63,7 +63,7 @@ func Extract(pass *analysis.Pass, obj types.Object, node *ast.GenDecl, callExpr common.Errorf(pass, callExpr, "subscription registration must have a topic") return optional.None[*schema.Subscription]() } - name := strcase.ToLowerSnake(varName) + name := strcase.ToLowerCamel(varName) topicRef = &schema.Ref{ Module: moduleIdent.Name, Name: name, diff --git a/go-runtime/schema/testdata/pubsub/pubsub.go b/go-runtime/schema/testdata/pubsub/pubsub.go index 2a729f4027..d2775b4d2f 100644 --- a/go-runtime/schema/testdata/pubsub/pubsub.go +++ b/go-runtime/schema/testdata/pubsub/pubsub.go @@ -32,11 +32,11 @@ var Payins = ftl.Topic[PayinEvent]("payins") var _ = ftl.Subscription(PublicBroadcast, "broadcastSubscription") -// public_broadcast is a topic that broadcasts payin events to the public. +// publicBroadcast is a topic that broadcasts payin events to the public. // out of order with subscription registration to test ordering doesn't matter. // //ftl:export -var PublicBroadcast = ftl.Topic[PayinEvent]("public_broadcast") +var PublicBroadcast = ftl.Topic[PayinEvent]("publicBroadcast") //ftl:verb export func Broadcast(ctx context.Context) error { diff --git a/go-runtime/schema/topic/analyzer.go b/go-runtime/schema/topic/analyzer.go index ef87d9db1b..aa63036353 100644 --- a/go-runtime/schema/topic/analyzer.go +++ b/go-runtime/schema/topic/analyzer.go @@ -19,7 +19,7 @@ const ( // Extractor extracts topics. var Extractor = common.NewCallDeclExtractor[*schema.Topic]("topic", Extract, ftlTopicFuncPath) -// expects: var NameLiteral = ftl.Topic[EventType]("name_literal") +// Extract expects: var NameLiteral = ftl.Topic[EventType]("nameLiteral") func Extract(pass *analysis.Pass, obj types.Object, node *ast.GenDecl, callExpr *ast.CallExpr, callPath string) optional.Option[*schema.Topic] { indexExpr, ok := callExpr.Fun.(*ast.IndexExpr) @@ -34,7 +34,7 @@ func Extract(pass *analysis.Pass, obj types.Object, node *ast.GenDecl, callExpr } topicName := common.ExtractStringLiteralArg(pass, callExpr, 0) - expTopicName := strcase.ToLowerSnake(topicName) + expTopicName := strcase.ToLowerCamel(strcase.ToUpperStrippedCamel(topicName)) if topicName != expTopicName { common.Errorf(pass, node, "unsupported topic name %q, did you mean to use %q?", topicName, expTopicName) return optional.None[*schema.Topic]() @@ -43,7 +43,7 @@ func Extract(pass *analysis.Pass, obj types.Object, node *ast.GenDecl, callExpr if len(node.Specs) > 0 { if t, ok := node.Specs[0].(*ast.ValueSpec); ok { varName := t.Names[0].Name - expVarName := strcase.ToUpperStrippedCamel(topicName) + expVarName := strcase.ToUpperCamel(topicName) if varName != expVarName { common.Errorf(pass, node, "unexpected topic variable name %q, did you mean %q?", varName, expVarName) return optional.None[*schema.Topic]() From 1028e65134630c6ae127720f19f78c2da65b27a5 Mon Sep 17 00:00:00 2001 From: Denise Li Date: Tue, 13 Aug 2024 17:49:48 -0400 Subject: [PATCH 26/35] feat: register db.sql metrics (#2305) Fixes https://github.com/TBD54566975/ftl/issues/2285 Register the standard otel database metrics using: https://github.com/XSAM/otelsql Found call sites by grepping for `sql.Open` and skipping all test code. Sample: ``` ScopeMetrics #2 ScopeMetrics SchemaURL: InstrumentationScope github.com/XSAM/otelsql 0.32.0 Metric #0 Descriptor: -> Name: db.sql.latency -> Description: The latency of calls in milliseconds -> Unit: ms -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 Data point attributes: -> method: Str(sql.conn.begin_tx) -> status: Str(ok) StartTimestamp: 2024-08-08 23:18:01.011762 +0000 UTC Timestamp: 2024-08-08 23:18:11.012177 +0000 UTC Count: 23 Sum: 17.082795 Min: 0.137584 Max: 3.233917 ``` --------- Co-authored-by: github-actions[bot] --- .../controller/sql/databasetesting/devel.go | 16 ++++++++-- cmd/ftl-controller/main.go | 7 +++-- cmd/ftl/cmd_box_run.go | 9 ++++-- cmd/ftl/cmd_serve.go | 9 ++++-- examples/go/echo/go.mod | 1 + examples/go/echo/go.sum | 4 +++ .../testdata/go/runtimereflection/go.mod | 1 + .../testdata/go/runtimereflection/go.sum | 4 +++ go.mod | 4 ++- go.sum | 2 ++ internal/modulecontext/database.go | 11 +++++-- internal/observability/client_test.go | 2 +- internal/reflect/reflect.go | 31 ++++++++++++++++++- internal/reflect/reflect_test.go | 21 +++++++++++++ 14 files changed, 108 insertions(+), 14 deletions(-) diff --git a/backend/controller/sql/databasetesting/devel.go b/backend/controller/sql/databasetesting/devel.go index b1c4e3dd18..e2a3a06c72 100644 --- a/backend/controller/sql/databasetesting/devel.go +++ b/backend/controller/sql/databasetesting/devel.go @@ -8,7 +8,9 @@ import ( "strings" "time" + "github.com/XSAM/otelsql" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/internal/log" @@ -29,9 +31,13 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*stdsql.DB, var conn *stdsql.DB for range 10 { - conn, err = stdsql.Open("pgx", noDBDSN.String()) + conn, err = otelsql.Open("pgx", noDBDSN.String()) if err == nil { defer conn.Close() + err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + if err != nil { + panic(err) + } break } logger.Debugf("Waiting for database to be ready: %v", err) @@ -72,9 +78,13 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*stdsql.DB, return nil, err } - realConn, err := stdsql.Open("pgx", dsn) + realConn, err := otelsql.Open("pgx", dsn) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to open database: %w", err) + } + err = otelsql.RegisterDBStatsMetrics(realConn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + if err != nil { + return nil, fmt.Errorf("failed to register db metrics: %w", err) } // Reset transient state in the database to a clean state for development purposes. // This includes things like resetting the state of async calls, leases, diff --git a/cmd/ftl-controller/main.go b/cmd/ftl-controller/main.go index 1b1ca03f38..20c4fa5f5e 100644 --- a/cmd/ftl-controller/main.go +++ b/cmd/ftl-controller/main.go @@ -2,15 +2,16 @@ package main import ( "context" - "database/sql" "fmt" "os" "strconv" "time" + "github.com/XSAM/otelsql" "github.com/alecthomas/kong" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "github.com/TBD54566975/ftl" "github.com/TBD54566975/ftl/backend/controller" @@ -51,7 +52,9 @@ func main() { kctx.FatalIfErrorf(err, "failed to initialize observability") // The FTL controller currently only supports DB as a configuration provider/resolver. - conn, err := sql.Open("pgx", cli.ControllerConfig.DSN) + conn, err := otelsql.Open("pgx", cli.ControllerConfig.DSN) + kctx.FatalIfErrorf(err) + err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) kctx.FatalIfErrorf(err) dal, err := dal.New(ctx, conn, encryptors) kctx.FatalIfErrorf(err) diff --git a/cmd/ftl/cmd_box_run.go b/cmd/ftl/cmd_box_run.go index fee285d3df..541dd679a9 100644 --- a/cmd/ftl/cmd_box_run.go +++ b/cmd/ftl/cmd_box_run.go @@ -2,13 +2,14 @@ package main import ( "context" - "database/sql" "fmt" "net/url" "time" + "github.com/XSAM/otelsql" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver "github.com/jpillora/backoff" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl/backend/controller" @@ -58,10 +59,14 @@ func (b *boxRunCmd) Run(ctx context.Context, projConfig projectconfig.Config) er } // Bring up the DB connection and DAL. - conn, err := sql.Open("pgx", config.DSN) + conn, err := otelsql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } + err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + if err != nil { + return fmt.Errorf("failed to register DB metrics: %w", err) + } encryptors, err := config.EncryptionKeys.Encryptors(false) if err != nil { return fmt.Errorf("failed to create encryptors: %w", err) diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index cb21fadc54..5956677ceb 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -2,7 +2,6 @@ package main import ( "context" - "database/sql" "errors" "fmt" "net" @@ -15,8 +14,10 @@ import ( "time" "connectrpc.com/connect" + "github.com/XSAM/otelsql" "github.com/alecthomas/types/optional" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl" @@ -148,10 +149,14 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini controllerCtx = cf.ContextWithSecrets(controllerCtx, sm) // Bring up the DB connection and DAL. - conn, err := sql.Open("pgx", config.DSN) + conn, err := otelsql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } + err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + if err != nil { + return fmt.Errorf("failed to register DB metrics: %w", err) + } encryptors, err := config.EncryptionKeys.Encryptors(false) if err != nil { return fmt.Errorf("failed to create encryptors: %w", err) diff --git a/examples/go/echo/go.mod b/examples/go/echo/go.mod index 272b973492..7769185838 100644 --- a/examples/go/echo/go.mod +++ b/examples/go/echo/go.mod @@ -10,6 +10,7 @@ require ( connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect connectrpc.com/otelconnect v0.7.1 // indirect + github.com/XSAM/otelsql v0.32.0 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect diff --git a/examples/go/echo/go.sum b/examples/go/echo/go.sum index 9fbb9ebc36..9569a27c55 100644 --- a/examples/go/echo/go.sum +++ b/examples/go/echo/go.sum @@ -6,6 +6,8 @@ connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= +github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= +github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= @@ -132,6 +134,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod index f190123044..ce3ab84d32 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod @@ -11,6 +11,7 @@ require ( connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect connectrpc.com/otelconnect v0.7.1 // indirect + github.com/XSAM/otelsql v0.32.0 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum index 9fbb9ebc36..9569a27c55 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum @@ -6,6 +6,8 @@ connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= +github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= +github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= @@ -132,6 +134,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= diff --git a/go.mod b/go.mod index 229522885f..46285e945b 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/BurntSushi/toml v1.4.0 github.com/TBD54566975/golang-tools v0.2.1 github.com/TBD54566975/scaffolder v1.0.0 + github.com/XSAM/otelsql v0.32.0 github.com/alecthomas/assert/v2 v2.10.0 github.com/alecthomas/atomic v0.1.0-alpha2 github.com/alecthomas/chroma/v2 v2.14.0 @@ -68,6 +69,7 @@ require ( golang.org/x/sync v0.8.0 golang.org/x/term v0.23.0 google.golang.org/protobuf v1.34.2 + gotest.tools/v3 v3.5.1 modernc.org/sqlite v1.32.0 ) @@ -87,6 +89,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/iancoleman/strcase v0.3.0 // indirect @@ -110,7 +113,6 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/tools v0.23.0 // indirect - gotest.tools/v3 v3.5.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect ) diff --git a/go.sum b/go.sum index 93f56bfac0..d6974f3379 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/TBD54566975/golang-tools v0.2.1 h1:jzP27dzvJRb43Z9xTbRCPOT/rZD43FZkqV github.com/TBD54566975/golang-tools v0.2.1/go.mod h1:rEEXIq0/pFgZqi/MTOq4DBmVpLHLgI9WocJWXYhu050= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= +github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= +github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= diff --git a/internal/modulecontext/database.go b/internal/modulecontext/database.go index a24080580b..7416a80df6 100644 --- a/internal/modulecontext/database.go +++ b/internal/modulecontext/database.go @@ -5,6 +5,9 @@ import ( "fmt" "strconv" + "github.com/XSAM/otelsql" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" ) @@ -19,9 +22,13 @@ type Database struct { // NewDatabase creates a Database that can be added to ModuleContext func NewDatabase(dbType DBType, dsn string) (Database, error) { - db, err := sql.Open("pgx", dsn) + db, err := otelsql.Open("pgx", dsn) if err != nil { - return Database{}, err + return Database{}, fmt.Errorf("failed to open database: %w", err) + } + err = otelsql.RegisterDBStatsMetrics(db, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + if err != nil { + return Database{}, fmt.Errorf("failed to register db metrics: %w", err) } return Database{ DSN: dsn, diff --git a/internal/observability/client_test.go b/internal/observability/client_test.go index 1cb3537ac4..b1582ba137 100644 --- a/internal/observability/client_test.go +++ b/internal/observability/client_test.go @@ -10,5 +10,5 @@ import ( func TestSchemaMismatch(t *testing.T) { dflt := resource.Default() - assert.Equal(t, dflt.SchemaURL(), schemaURL, `change import in client.go to: semconv "go.opentelemetry.io/otel/semconv/v%s"`, path.Base(dflt.SchemaURL())) + assert.Equal(t, dflt.SchemaURL(), schemaURL, `in every file that imports go.opentelemetry.io/otel/semconv, change the import to: semconv "go.opentelemetry.io/otel/semconv/v%s"`, path.Base(dflt.SchemaURL())) } diff --git a/internal/reflect/reflect.go b/internal/reflect/reflect.go index 079c4edb93..c0a19776eb 100644 --- a/internal/reflect/reflect.go +++ b/internal/reflect/reflect.go @@ -13,6 +13,7 @@ package reflect import ( + "container/list" "fmt" "reflect" "strings" @@ -131,6 +132,11 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { return src } + // Special case list.List to handle its internal structure + if reflect.TypeOf(src) == reflect.TypeFor[*list.List]() { + return copyList(src.(*list.List), ptrs, copyConf) + } + // Look up the corresponding copy function. switch v.Kind() { case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, @@ -139,7 +145,11 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { reflect.Complex64, reflect.Complex128, reflect.Func: dst = copyPremitive(src, ptrs, copyConf) case reflect.String: - dst = strings.Clone(src.(string)) + if v.Type() == reflect.TypeFor[string]() { + dst = strings.Clone(src.(string)) + } else { + dst = copyStringAlias(src, ptrs, copyConf) + } case reflect.Slice: dst = copySlice(src, ptrs, copyConf) case reflect.Array: @@ -160,6 +170,18 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { return } +func copyList(src *list.List, ptrs map[uintptr]any, copyConf *copyConfig) *list.List { + if src == nil { + return nil + } + dst := list.New() + for e := src.Front(); e != nil; e = e.Next() { + copiedValue := copyAny(e.Value, ptrs, copyConf) + dst.PushBack(copiedValue) + } + return dst +} + func copyPremitive(src any, ptr map[uintptr]any, copyConf *copyConfig) (dst any) { kind := reflect.ValueOf(src).Kind() switch kind { @@ -170,6 +192,13 @@ func copyPremitive(src any, ptr map[uintptr]any, copyConf *copyConfig) (dst any) return } +func copyStringAlias(src any, ptr map[uintptr]any, copyConf *copyConfig) any { + v := reflect.ValueOf(src) + dc := reflect.New(v.Type()).Elem() + dc.Set(v) + return dc.Interface() +} + func copySlice(x any, ptrs map[uintptr]any, copyConf *copyConfig) any { v := reflect.ValueOf(x) kind := v.Kind() diff --git a/internal/reflect/reflect_test.go b/internal/reflect/reflect_test.go index a6f138e042..e525943aaf 100644 --- a/internal/reflect/reflect_test.go +++ b/internal/reflect/reflect_test.go @@ -1,9 +1,30 @@ package reflect import ( + "container/list" "testing" + + "gotest.tools/v3/assert" ) +type mystring string +type structWithMystring struct { + str mystring +} + +func TestAliasedString(t *testing.T) { + output := DeepCopy(structWithMystring{"asdf"}) + assert.Equal(t, output, structWithMystring{"asdf"}) +} + +func TestListElements(t *testing.T) { + l := list.New() + l.PushBack("one") + output := DeepCopy(l) + assert.Equal(t, output.Front().Value, l.Front().Value) + assert.Equal(t, output.Len(), l.Len()) +} + type structOfPointers struct { intPtr *int floatPtr *float64 From e3c96efbf9bd0f8ce9aff6a785288f445b8a72a1 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 14 Aug 2024 10:49:05 +1000 Subject: [PATCH 27/35] docs: add feature matrix (#2347) Probably incomplete and inaccurate, we will iterate on it. Fixes #2344 image --- docs/content/docs/reference/matrix.md | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/content/docs/reference/matrix.md diff --git a/docs/content/docs/reference/matrix.md b/docs/content/docs/reference/matrix.md new file mode 100644 index 0000000000..817281f7b4 --- /dev/null +++ b/docs/content/docs/reference/matrix.md @@ -0,0 +1,43 @@ ++++ +title = "Feature Matrix" +description = "Matrix showing which FTL features are supported by each language" +date = 2021-05-01T08:20:00+00:00 +updated = 2021-05-01T08:20:00+00:00 +draft = false +weight = 120 +sort_by = "weight" +template = "docs/page.html" + +[extra] +toc = true +top = false ++++ + +| System | Feature | Go | JVM | Rust | +| :------------ | :-------------- | :-- | :-- | :--- | +| **Types** | Basic Types | ✔️ | ✔️ | ️ ✔️ | +| | Optional Type | ✔️ | ✔️ | | +| | Unit Type | ✔️ | ✔️ | | +| | Empty Type | ✔️ | ✔️ | | +| | Generic Types | ✔️ | ️ | | +| | Type Aliases | ✔️ | ️ | | +| | Value Enums | ✔️ | ️ | | +| | Type Enums | ✔️ | ️ | | +| | Visibility | ✔️ | ✔️ | | +| **Verbs** | Verb | ✔️ | ✔️ | ️✔️ | +| | Sink | ✔️ | ✔️ | | +| | Source | ✔️ | ✔️ | | +| | Empty | ✔️ | ✔️ | | +| | Visibility | ✔️ | ✔️ | | +| **Core** | FSM | ✔️ | ️ | | +| | Leases | ✔️ | ✔️ | | +| | Cron | ✔️ | | | +| | Config | ✔️ | ✔️ | | +| | Secrets | ✔️ | | | +| | HTTP Ingress | ✔️ | ✔️ | | +| **Resources** | PostgreSQL | ✔️ | ️ | | +| | MySQL | | | | +| | Kafka | | | | +| **PubSub** | Declaring Topic | ✔️ | ✔️ | | +| | Subscribing | ✔️ | ✔️ | | +| | Publishing | ✔️ | ✔️ | | From d5666b9e4363ae042d69a0d92ea627e69a1f3487 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Wed, 14 Aug 2024 11:24:59 +1000 Subject: [PATCH 28/35] fix: asm leader failing to read and write lease metadata (#2349) fixes #2343 --- backend/controller/dal/lease.go | 8 +++++--- backend/controller/leader/leader.go | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/backend/controller/dal/lease.go b/backend/controller/dal/lease.go index 7bcfc64fc0..8bbc1fd5b0 100644 --- a/backend/controller/dal/lease.go +++ b/backend/controller/dal/lease.go @@ -96,7 +96,7 @@ func (d *DAL) AcquireLease(ctx context.Context, key leases.Key, ttl time.Duratio return nil, nil, fmt.Errorf("failed to marshal lease metadata: %w", err) } } - idempotencyKey, err := d.db.NewLease(ctx, key, sqltypes.Duration(ttl), pqtype.NullRawMessage{RawMessage: metadataBytes}) + idempotencyKey, err := d.db.NewLease(ctx, key, sqltypes.Duration(ttl), pqtype.NullRawMessage{RawMessage: metadataBytes, Valid: true}) if err != nil { err = dalerrs.TranslatePGError(err) if errors.Is(err, dalerrs.ErrConflict) { @@ -130,8 +130,10 @@ func (d *DAL) GetLeaseInfo(ctx context.Context, key leases.Key, metadata any) (e if err != nil { return expiry, dalerrs.TranslatePGError(err) } - if err := json.Unmarshal(l.Metadata.RawMessage, metadata); err != nil { - return expiry, fmt.Errorf("could not unmarshal lease metadata: %w", err) + if l.Metadata.Valid { + if err := json.Unmarshal(l.Metadata.RawMessage, metadata); err != nil { + return expiry, fmt.Errorf("could not unmarshal lease metadata: %w", err) + } } return l.ExpiresAt, nil } diff --git a/backend/controller/leader/leader.go b/backend/controller/leader/leader.go index 643adc327e..79c4081a2b 100644 --- a/backend/controller/leader/leader.go +++ b/backend/controller/leader/leader.go @@ -182,7 +182,9 @@ func (c *Coordinator[P]) createFollower() (out P, err error) { } return out, fmt.Errorf("could not get lease for %s: %w", c.key, err) } - if urlString == c.advertise.String() { + if urlString == "" { + return out, fmt.Errorf("%s leader lease missing url in metadata", c.key) + } else if urlString == c.advertise.String() { // This prevents endless loops after a lease breaks. // If we create a follower pointing locally, the receiver will likely try to then call the leader, which starts the loop again. return out, fmt.Errorf("could not follow %s leader at own url: %s", c.key, urlString) From da693726b2110659e1f9d14eb74fcd9222bcf01d Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Wed, 14 Aug 2024 11:54:23 +1000 Subject: [PATCH 29/35] fix: also require camel case subscription names (#2342) This makes naming more consistent. --- backend/controller/pubsub/integration_test.go | 8 ++++---- .../pubsub/testdata/go/subscriber/subscriber.go | 16 +++++++++------- go-runtime/schema/subscription/analyzer.go | 8 +++++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/backend/controller/pubsub/integration_test.go b/backend/controller/pubsub/integration_test.go index 9438a3d2ba..bc8dbdd0b9 100644 --- a/backend/controller/pubsub/integration_test.go +++ b/backend/controller/pubsub/integration_test.go @@ -34,7 +34,7 @@ func TestPubSub(t *testing.T) { WHERE state = 'success' AND origin = '%s' - `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "test_subscription"}}.String()), + `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "testSubscription"}}.String()), events), ) } @@ -103,7 +103,7 @@ func TestRetry(t *testing.T) { state = 'error' AND catching = false AND origin = '%s' - `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomed_subscription"}}.String()), + `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomedSubscription"}}.String()), 1+retriesPerCall), // check that there is one failed attempt to catch (we purposely fail the first one) @@ -116,7 +116,7 @@ func TestRetry(t *testing.T) { AND error = 'call to verb subscriber.catch failed: catching error' AND catching = true AND origin = '%s' - `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomed_subscription"}}.String()), + `, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomedSubscription"}}.String()), 1), // check that there is one successful attempt to catch (we succeed the second one as long as we receive the correct error in the request) @@ -129,7 +129,7 @@ func TestRetry(t *testing.T) { AND error IS NULL AND catching = true AND origin = '%s' -`, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomed_subscription"}}.String()), +`, dal.AsyncOriginPubSub{Subscription: schema.RefKey{Module: "subscriber", Name: "doomedSubscription"}}.String()), 1), ) } diff --git a/backend/controller/pubsub/testdata/go/subscriber/subscriber.go b/backend/controller/pubsub/testdata/go/subscriber/subscriber.go index 068671661a..bc719e49e4 100644 --- a/backend/controller/pubsub/testdata/go/subscriber/subscriber.go +++ b/backend/controller/pubsub/testdata/go/subscriber/subscriber.go @@ -3,30 +3,32 @@ package subscriber import ( "context" "fmt" - "ftl/builtin" - "ftl/publisher" "strings" "time" - "github.com/TBD54566975/ftl/go-runtime/ftl" // Import the FTL SDK. + "ftl/builtin" + "ftl/publisher" + "github.com/alecthomas/atomic" + + "github.com/TBD54566975/ftl/go-runtime/ftl" // Import the FTL SDK. ) -var _ = ftl.Subscription(publisher.TestTopic, "test_subscription") +var _ = ftl.Subscription(publisher.TestTopic, "testSubscription") var catchCount atomic.Value[int] //ftl:verb -//ftl:subscribe test_subscription +//ftl:subscribe testSubscription func Consume(ctx context.Context, req publisher.PubSubEvent) error { ftl.LoggerFromContext(ctx).Infof("Subscriber is consuming %v", req.Time) return nil } -var _ = ftl.Subscription(publisher.Topic2, "doomed_subscription") +var _ = ftl.Subscription(publisher.Topic2, "doomedSubscription") //ftl:verb -//ftl:subscribe doomed_subscription +//ftl:subscribe doomedSubscription //ftl:retry 2 1s 1s catch catch func ConsumeButFailAndRetry(ctx context.Context, req publisher.PubSubEvent) error { return fmt.Errorf("always error: event %v", req.Time) diff --git a/go-runtime/schema/subscription/analyzer.go b/go-runtime/schema/subscription/analyzer.go index d4c4472be3..84dc481be6 100644 --- a/go-runtime/schema/subscription/analyzer.go +++ b/go-runtime/schema/subscription/analyzer.go @@ -73,9 +73,15 @@ func Extract(pass *analysis.Pass, obj types.Object, node *ast.GenDecl, callExpr return optional.None[*schema.Subscription]() } + subName := common.ExtractStringLiteralArg(pass, callExpr, 1) + expSubName := strcase.ToLowerCamel(subName) + if subName != expSubName { + common.Errorf(pass, node, "unsupported subscription name %q, did you mean to use %q?", subName, expSubName) + return optional.None[*schema.Subscription]() + } subscription := &schema.Subscription{ Pos: common.GoPosToSchemaPos(pass.Fset, callExpr.Pos()), - Name: common.ExtractStringLiteralArg(pass, callExpr, 1), + Name: subName, Topic: topicRef, } common.ApplyMetadata[*schema.Subscription](pass, obj, func(md *common.ExtractedMetadata) { From 2a3edbcce2b00cdbb99be53da4175bec6028b8fb Mon Sep 17 00:00:00 2001 From: gak Date: Wed, 14 Aug 2024 12:12:34 +1000 Subject: [PATCH 30/35] feat(KMS): derive keys for logs and async (#2338) Fixes #2290 Follows #2312 Needs work: #2346 #2348 > [!CAUTION] > Will nuke logs and async columns! - Uses KMS via tink `FTL_KMS_URI`, so `fake-kms://` or `aws-kms://` will work. Omitting will not encrypt. - Remove old plaintext keys envs. --------- Co-authored-by: github-actions[bot] Co-authored-by: Matt Toohey --- backend/controller/controller.go | 50 +--- .../cronjobs/cronjobs_integration_test.go | 8 +- backend/controller/cronjobs/cronjobs_test.go | 2 +- backend/controller/cronjobs/sql/models.go | 10 +- backend/controller/dal/async_calls.go | 19 +- backend/controller/dal/async_calls_test.go | 4 +- backend/controller/dal/dal.go | 44 ++- backend/controller/dal/dal_test.go | 7 +- backend/controller/dal/encryption.go | 106 ++++++++ backend/controller/dal/events.go | 9 +- backend/controller/dal/fsm.go | 3 +- .../controller/dal/fsm_integration_test.go | 2 +- backend/controller/dal/fsm_test.go | 3 +- backend/controller/dal/lease_test.go | 4 +- backend/controller/dal/pubsub.go | 4 +- backend/controller/sql/migrate/migrate.go | 2 +- backend/controller/sql/models.go | 10 +- backend/controller/sql/querier.go | 4 +- backend/controller/sql/queries.sql | 11 +- backend/controller/sql/queries.sql.go | 31 ++- .../20240812011321_derive_encryption.sql | 19 ++ cmd/ftl-controller/main.go | 10 +- cmd/ftl/cmd_box_run.go | 6 +- cmd/ftl/cmd_serve.go | 8 +- common/configuration/sql/models.go | 10 +- integration/harness.go | 7 +- internal/encryption/encryption.go | 253 +++--------------- internal/encryption/encryption_test.go | 65 +---- internal/encryption/integration_test.go | 5 +- 29 files changed, 300 insertions(+), 416 deletions(-) create mode 100644 backend/controller/dal/encryption.go create mode 100644 backend/controller/sql/schema/20240812011321_derive_encryption.sql diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 0ef15118de..3b79041c1c 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -55,7 +55,6 @@ import ( cf "github.com/TBD54566975/ftl/common/configuration" frontend "github.com/TBD54566975/ftl/frontend" "github.com/TBD54566975/ftl/internal/cors" - "github.com/TBD54566975/ftl/internal/encryption" ftlhttp "github.com/TBD54566975/ftl/internal/http" "github.com/TBD54566975/ftl/internal/log" ftlmaps "github.com/TBD54566975/ftl/internal/maps" @@ -85,42 +84,6 @@ func (c *CommonConfig) Validate() error { return nil } -// EncryptionKeys for the controller config. -// Deprecated: Will remove this at some stage. -type EncryptionKeys struct { - Logs string `name:"log-key" help:"Key for sensitive log data in internal FTL tables." env:"FTL_LOG_ENCRYPTION_KEY"` - Async string `name:"async-key" help:"Key for sensitive async call data in internal FTL tables." env:"FTL_ASYNC_ENCRYPTION_KEY"` -} - -func (e EncryptionKeys) Encryptors(required bool) (*dal.Encryptors, error) { - encryptors := dal.Encryptors{} - if e.Logs != "" { - enc, err := encryption.NewForKeyOrURI(e.Logs) - if err != nil { - return nil, fmt.Errorf("could not create log encryptor: %w", err) - } - encryptors.Logs = enc - } else if required { - return nil, fmt.Errorf("FTL_LOG_ENCRYPTION_KEY is required") - } else { - encryptors.Logs = encryption.NoOpEncryptor{} - } - - if e.Async != "" { - enc, err := encryption.NewForKeyOrURI(e.Async) - if err != nil { - return nil, fmt.Errorf("could not create async calls encryptor: %w", err) - } - encryptors.Async = enc - } else if required { - return nil, fmt.Errorf("FTL_ASYNC_ENCRYPTION_KEY is required") - } else { - encryptors.Async = encryption.NoOpEncryptor{} - } - - return &encryptors, nil -} - type Config struct { Bind *url.URL `help:"Socket to bind to." default:"http://127.0.0.1:8892" env:"FTL_CONTROLLER_BIND"` IngressBind *url.URL `help:"Socket to bind to for ingress." default:"http://127.0.0.1:8891" env:"FTL_CONTROLLER_INGRESS_BIND"` @@ -135,8 +98,7 @@ type Config struct { ModuleUpdateFrequency time.Duration `help:"Frequency to send module updates." default:"30s"` EventLogRetention *time.Duration `help:"Delete call logs after this time period. 0 to disable" env:"FTL_EVENT_LOG_RETENTION" default:"24h"` ArtefactChunkSize int `help:"Size of each chunk streamed to the client." default:"1048576"` - KMSURI *url.URL `help:"URI for KMS key e.g. aws-kms://arn:aws:kms:ap-southeast-2:12345:key/0000-1111" env:"FTL_KMS_URI"` - EncryptionKeys + KMSURI *string `help:"URI for KMS key e.g. with fake-kms:// or aws-kms://arn:aws:kms:ap-southeast-2:12345:key/0000-1111" env:"FTL_KMS_URI"` CommonConfig } @@ -150,7 +112,7 @@ func (c *Config) SetDefaults() { } // Start the Controller. Blocks until the context is cancelled. -func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScaling, conn *sql.DB, encryptors *dal.Encryptors) error { +func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScaling, conn *sql.DB) error { config.SetDefaults() logger := log.FromContext(ctx) @@ -171,7 +133,7 @@ func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScali logger.Infof("Web console available at: %s", config.Bind) } - svc, err := New(ctx, conn, config, runnerScaling, encryptors) + svc, err := New(ctx, conn, config, runnerScaling) if err != nil { return err } @@ -253,7 +215,7 @@ type Service struct { asyncCallsLock sync.Mutex } -func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling.RunnerScaling, encryptors *dal.Encryptors) (*Service, error) { +func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling.RunnerScaling) (*Service, error) { key := config.Key if config.Key.IsZero() { key = model.NewControllerKey(config.Bind.Hostname(), config.Bind.Port()) @@ -267,7 +229,7 @@ func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling config.ControllerTimeout = time.Second * 5 } - db, err := dal.New(ctx, conn, encryptors) + db, err := dal.New(ctx, conn, optional.Ptr[string](config.KMSURI)) if err != nil { return nil, fmt.Errorf("failed to create DAL: %w", err) } @@ -1492,7 +1454,7 @@ func (s *Service) catchAsyncCall(ctx context.Context, logger *log.Logger, call * originalResult := either.RightOf[[]byte](originalError) request := map[string]any{ - "request": call.Request, + "request": json.RawMessage(call.Request), "error": originalError, } body, err := json.Marshal(request) diff --git a/backend/controller/cronjobs/cronjobs_integration_test.go b/backend/controller/cronjobs/cronjobs_integration_test.go index 61c250e34a..62d9984c5c 100644 --- a/backend/controller/cronjobs/cronjobs_integration_test.go +++ b/backend/controller/cronjobs/cronjobs_integration_test.go @@ -9,13 +9,15 @@ import ( "testing" "time" + "github.com/alecthomas/assert/v2" + "github.com/alecthomas/types/optional" + "github.com/benbjohnson/clock" + db "github.com/TBD54566975/ftl/backend/controller/cronjobs/dal" parentdb "github.com/TBD54566975/ftl/backend/controller/dal" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" in "github.com/TBD54566975/ftl/integration" "github.com/TBD54566975/ftl/internal/log" - "github.com/alecthomas/assert/v2" - "github.com/benbjohnson/clock" ) func TestServiceWithRealDal(t *testing.T) { @@ -26,7 +28,7 @@ func TestServiceWithRealDal(t *testing.T) { conn := sqltest.OpenForTesting(ctx, t) dal := db.New(conn) - parentDAL, err := parentdb.New(ctx, conn, parentdb.NoOpEncryptors()) + parentDAL, err := parentdb.New(ctx, conn, optional.None[string]()) assert.NoError(t, err) // Using a real clock because real db queries use db clock diff --git a/backend/controller/cronjobs/cronjobs_test.go b/backend/controller/cronjobs/cronjobs_test.go index bba46f5a42..715476c932 100644 --- a/backend/controller/cronjobs/cronjobs_test.go +++ b/backend/controller/cronjobs/cronjobs_test.go @@ -37,7 +37,7 @@ func TestServiceWithMockDal(t *testing.T) { attemptCountMap: map[string]int{}, } conn := sqltest.OpenForTesting(ctx, t) - parentDAL, err := db.New(ctx, conn, db.NoOpEncryptors()) + parentDAL, err := db.New(ctx, conn, optional.None[string]()) assert.NoError(t, err) testServiceWithDal(ctx, t, mockDal, parentDAL, clk) diff --git a/backend/controller/cronjobs/sql/models.go b/backend/controller/cronjobs/sql/models.go index 5b5c1c76e4..731679ea0f 100644 --- a/backend/controller/cronjobs/sql/models.go +++ b/backend/controller/cronjobs/sql/models.go @@ -378,8 +378,8 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request json.RawMessage - Response pqtype.NullRawMessage + Request []byte + Response []byte Error optional.Option[string] RemainingAttempts int32 Backoff sqltypes.Duration @@ -429,6 +429,12 @@ type DeploymentArtefact struct { Path string } +type EncryptionKey struct { + ID int64 + Key []byte + CreatedAt time.Time +} + type Event struct { ID int64 TimeStamp time.Time diff --git a/backend/controller/dal/async_calls.go b/backend/controller/dal/async_calls.go index 696bb9fdf3..e4ab2f4688 100644 --- a/backend/controller/dal/async_calls.go +++ b/backend/controller/dal/async_calls.go @@ -2,7 +2,6 @@ package dal import ( "context" - "encoding/json" "errors" "fmt" "time" @@ -15,6 +14,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/encryption" ) type asyncOriginParseRoot struct { @@ -77,7 +77,7 @@ type AsyncCall struct { Origin AsyncOrigin Verb schema.RefKey CatchVerb optional.Option[schema.RefKey] - Request json.RawMessage + Request []byte ScheduledAt time.Time QueueDepth int64 ParentRequestKey optional.Option[string] @@ -115,8 +115,7 @@ func (d *DAL) AcquireAsyncCall(ctx context.Context) (call *AsyncCall, err error) return nil, fmt.Errorf("failed to parse origin key %q: %w", row.Origin, err) } - var decryptedRequest json.RawMessage - err = d.encryptors.Async.DecryptJSON(row.Request, &decryptedRequest) + decryptedRequest, err := d.decrypt(encryption.AsyncSubKey, row.Request) if err != nil { return nil, fmt.Errorf("failed to decrypt async call request: %w", err) } @@ -159,7 +158,11 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, didScheduleAnotherCall = false switch result := result.(type) { case either.Left[[]byte, string]: // Successful response. - _, err = tx.db.SucceedAsyncCall(ctx, result.Get(), call.ID) + encryptedResult, err := d.encrypt(encryption.AsyncSubKey, result.Get()) + if err != nil { + return false, fmt.Errorf("failed to encrypt async call result: %w", err) + } + _, err = tx.db.SucceedAsyncCall(ctx, encryptedResult, call.ID) if err != nil { return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck } @@ -224,10 +227,14 @@ func (d *DAL) LoadAsyncCall(ctx context.Context, id int64) (*AsyncCall, error) { if err != nil { return nil, fmt.Errorf("failed to parse origin key %q: %w", row.Origin, err) } + request, err := d.decrypt(encryption.AsyncSubKey, row.Request) + if err != nil { + return nil, fmt.Errorf("failed to decrypt async call request: %w", err) + } return &AsyncCall{ ID: row.ID, Verb: row.Verb, Origin: origin, - Request: row.Request, + Request: request, }, nil } diff --git a/backend/controller/dal/async_calls_test.go b/backend/controller/dal/async_calls_test.go index 7aab05128f..965a3d6a24 100644 --- a/backend/controller/dal/async_calls_test.go +++ b/backend/controller/dal/async_calls_test.go @@ -4,6 +4,8 @@ import ( "context" "testing" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/internal/log" @@ -13,7 +15,7 @@ import ( func TestNoCallToAcquire(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) _, err = dal.AcquireAsyncCall(ctx) diff --git a/backend/controller/dal/dal.go b/backend/controller/dal/dal.go index 55229c1b9c..9e1f7b4ac1 100644 --- a/backend/controller/dal/dal.go +++ b/backend/controller/dal/dal.go @@ -210,35 +210,30 @@ func WithReservation(ctx context.Context, reservation Reservation, fn func() err return reservation.Commit(ctx) } -func New(ctx context.Context, conn *stdsql.DB, encryptors *Encryptors) (*DAL, error) { - return &DAL{ +func New(ctx context.Context, conn *stdsql.DB, kmsURL optional.Option[string]) (*DAL, error) { + d := &DAL{ db: sql.NewDB(conn), DeploymentChanges: pubsub.New[DeploymentNotification](), - encryptors: encryptors, - }, nil + kmsURL: kmsURL, + } + + if err := d.setupEncryptor(ctx); err != nil { + return nil, fmt.Errorf("failed to setup encryptor: %w", err) + } + + return d, nil } type DAL struct { - db sql.DBI - encryptors *Encryptors + db sql.DBI + + kmsURL optional.Option[string] + encryptor encryption.DataEncryptor // DeploymentChanges is a Topic that receives changes to the deployments table. DeploymentChanges *pubsub.Topic[DeploymentNotification] } -type Encryptors struct { - Logs encryption.Encryptable - Async encryption.Encryptable -} - -// NoOpEncryptors do not encrypt potentially sensitive data. -func NoOpEncryptors() *Encryptors { - return &Encryptors{ - Logs: encryption.NoOpEncryptor{}, - Async: encryption.NoOpEncryptor{}, - } -} - // Tx is DAL within a transaction. type Tx struct { *DAL @@ -285,7 +280,8 @@ func (d *DAL) Begin(ctx context.Context) (*Tx, error) { return &Tx{&DAL{ db: tx, DeploymentChanges: d.DeploymentChanges, - encryptors: d.encryptors, + kmsURL: d.kmsURL, + encryptor: d.encryptor, }}, nil } @@ -713,7 +709,7 @@ func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey return dalerrs.TranslatePGError(err) } } - payload, err := d.encryptors.Logs.EncryptJSON(map[string]any{ + payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]interface{}{ "prev_min_replicas": deployment.MinReplicas, "min_replicas": minReplicas, }) @@ -786,7 +782,7 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl } } - payload, err := d.encryptors.Logs.EncryptJSON(map[string]any{ + payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]any{ "min_replicas": int32(minReplicas), "replaced": replacedDeploymentKey, }) @@ -1061,7 +1057,7 @@ func (d *DAL) InsertLogEvent(ctx context.Context, log *LogEvent) error { "error": log.Error, "stack": log.Stack, } - encryptedPayload, err := d.encryptors.Logs.EncryptJSON(payload) + encryptedPayload, err := d.encryptJSON(encryption.LogsSubKey, payload) if err != nil { return fmt.Errorf("failed to encrypt log payload: %w", err) } @@ -1141,7 +1137,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { if pr, ok := call.ParentRequestKey.Get(); ok { parentRequestKey = optional.Some(pr.String()) } - payload, err := d.encryptors.Logs.EncryptJSON(map[string]any{ + payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]any{ "duration_ms": call.Duration.Milliseconds(), "request": call.Request, "response": call.Response, diff --git a/backend/controller/dal/dal_test.go b/backend/controller/dal/dal_test.go index 0f3be9a3a9..ee3618c442 100644 --- a/backend/controller/dal/dal_test.go +++ b/backend/controller/dal/dal_test.go @@ -25,7 +25,7 @@ import ( func TestDAL(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) assert.NotZero(t, dal) var testContent = bytes.Repeat([]byte("sometestcontentthatislongerthanthereadbuffer"), 100) @@ -235,7 +235,7 @@ func TestDAL(t *testing.T) { DeploymentKey: deploymentKey, RequestKey: optional.Some(requestKey), Request: []byte("{}"), - Response: []byte(`{"time": "now"}`), + Response: []byte(`{"time":"now"}`), DestVerb: schema.Ref{Module: "time", Name: "time"}, } t.Run("InsertCallEvent", func(t *testing.T) { @@ -396,6 +396,7 @@ func normaliseEvents(events []Event) []Event { f.Set(reflect.Zero(f.Type())) events[i] = event } + return events } @@ -407,7 +408,7 @@ func assertEventsEqual(t *testing.T, expected, actual []Event) { func TestDeleteOldEvents(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) var testContent = bytes.Repeat([]byte("sometestcontentthatislongerthanthereadbuffer"), 100) diff --git a/backend/controller/dal/encryption.go b/backend/controller/dal/encryption.go new file mode 100644 index 0000000000..3bedc9476a --- /dev/null +++ b/backend/controller/dal/encryption.go @@ -0,0 +1,106 @@ +package dal + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/internal/encryption" + "github.com/TBD54566975/ftl/internal/log" +) + +func (d *DAL) encrypt(subKey encryption.SubKey, cleartext []byte) ([]byte, error) { + if d.encryptor == nil { + return nil, fmt.Errorf("encryptor not set") + } + + v, err := d.encryptor.Encrypt(subKey, cleartext) + if err != nil { + return nil, fmt.Errorf("failed to encrypt binary with subkey %s: %w", subKey, err) + } + + return v, nil +} + +func (d *DAL) decrypt(subKey encryption.SubKey, encrypted []byte) ([]byte, error) { + if d.encryptor == nil { + return nil, fmt.Errorf("encryptor not set") + } + + v, err := d.encryptor.Decrypt(subKey, encrypted) + if err != nil { + return nil, fmt.Errorf("failed to decrypt binary with subkey %s: %w", subKey, err) + } + + return v, nil +} + +func (d *DAL) encryptJSON(subKey encryption.SubKey, v any) ([]byte, error) { + serialized, err := json.Marshal(v) + if err != nil { + return nil, fmt.Errorf("failed to marshal JSON: %w", err) + } + + return d.encrypt(subKey, serialized) +} + +func (d *DAL) decryptJSON(subKey encryption.SubKey, encrypted []byte, v any) error { //nolint:unparam + decrypted, err := d.decrypt(subKey, encrypted) + if err != nil { + return fmt.Errorf("failed to decrypt json with subkey %s: %w", subKey, err) + } + + if err = json.Unmarshal(decrypted, v); err != nil { + return fmt.Errorf("failed to unmarshal JSON: %w", err) + } + + return nil +} + +// setupEncryptor sets up the encryptor for the DAL. +// It will either create a key or load the existing one. +// If the KMS URL is not set, it will use a NoOpEncryptor which does not encrypt anything. +func (d *DAL) setupEncryptor(ctx context.Context) (err error) { + logger := log.FromContext(ctx) + tx, err := d.Begin(ctx) + if err != nil { + return fmt.Errorf("failed to begin transaction: %w", err) + } + defer tx.CommitOrRollback(ctx, &err) + + url, ok := d.kmsURL.Get() + if !ok { + logger.Infof("KMS URL not set, encryption not enabled") + d.encryptor = encryption.NewNoOpEncryptor() + return nil + } + + encryptedKey, err := tx.db.GetOnlyEncryptionKey(ctx) + if err != nil { + if dal.IsNotFound(err) { + logger.Infof("No encryption key found, generating a new one") + encryptor, err := encryption.NewKMSEncryptorGenerateKey(url, nil) + if err != nil { + return fmt.Errorf("failed to create encryptor for generation: %w", err) + } + d.encryptor = encryptor + + if err = tx.db.CreateOnlyEncryptionKey(ctx, encryptor.GetEncryptedKeyset()); err != nil { + return fmt.Errorf("failed to create only encryption key: %w", err) + } + + return nil + } + return fmt.Errorf("failed to get only encryption key: %w", err) + } + + logger.Debugf("Encryption key found, using it") + encryptor, err := encryption.NewKMSEncryptorWithKMS(url, nil, encryptedKey) + if err != nil { + return fmt.Errorf("failed to create encryptor with encrypted key: %w", err) + } + d.encryptor = encryptor + + return nil +} diff --git a/backend/controller/dal/events.go b/backend/controller/dal/events.go index 8889d1c433..75babd7fe4 100644 --- a/backend/controller/dal/events.go +++ b/backend/controller/dal/events.go @@ -13,6 +13,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/sql" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/model" ) @@ -348,7 +349,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey switch row.Type { case sql.EventTypeLog: var jsonPayload eventLogJSON - if err := d.encryptors.Logs.DecryptJSON(row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt log event: %w", err) } @@ -370,7 +371,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeCall: var jsonPayload eventCallJSON - if err := d.encryptors.Logs.DecryptJSON(row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } var sourceVerb optional.Option[schema.Ref] @@ -395,7 +396,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeDeploymentCreated: var jsonPayload eventDeploymentCreatedJSON - if err := d.encryptors.Logs.DecryptJSON(row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } out = append(out, &DeploymentCreatedEvent{ @@ -410,7 +411,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeDeploymentUpdated: var jsonPayload eventDeploymentUpdatedJSON - if err := d.encryptors.Logs.DecryptJSON(row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } out = append(out, &DeploymentUpdatedEvent{ diff --git a/backend/controller/dal/fsm.go b/backend/controller/dal/fsm.go index b463b39a5d..1311c76ed5 100644 --- a/backend/controller/dal/fsm.go +++ b/backend/controller/dal/fsm.go @@ -15,6 +15,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/encryption" ) // StartFSMTransition sends an event to an executing instance of an FSM. @@ -31,7 +32,7 @@ import ( // // Note: no validation of the FSM is performed. func (d *DAL) StartFSMTransition(ctx context.Context, fsm schema.RefKey, executionKey string, destinationState schema.RefKey, request json.RawMessage, retryParams schema.RetryParams) (err error) { - encryptedRequest, err := d.encryptors.Async.EncryptJSON(request) + encryptedRequest, err := d.encryptJSON(encryption.AsyncSubKey, request) if err != nil { return fmt.Errorf("failed to encrypt FSM request: %w", err) } diff --git a/backend/controller/dal/fsm_integration_test.go b/backend/controller/dal/fsm_integration_test.go index a783e79f59..6ae5a00e83 100644 --- a/backend/controller/dal/fsm_integration_test.go +++ b/backend/controller/dal/fsm_integration_test.go @@ -98,7 +98,7 @@ func TestFSMRetry(t *testing.T) { in.Call("fsmretry", "startTransitionToThree", in.Obj{"id": "2"}, func(t testing.TB, response any) {}), in.Call("fsmretry", "startTransitionToTwo", in.Obj{"id": "3", "failCatch": true}, func(t testing.TB, response any) {}), - in.Sleep(9*time.Second), //6s is longest run of retries + in.Sleep(7*time.Second), //6s is longest run of retries // First two FSMs instances should have failed // Third one will not as it is still catching diff --git a/backend/controller/dal/fsm_test.go b/backend/controller/dal/fsm_test.go index 684768be90..7f1eabe032 100644 --- a/backend/controller/dal/fsm_test.go +++ b/backend/controller/dal/fsm_test.go @@ -2,6 +2,7 @@ package dal import ( "context" + "github.com/alecthomas/types/optional" "testing" "time" @@ -17,7 +18,7 @@ import ( func TestSendFSMEvent(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) _, err = dal.AcquireAsyncCall(ctx) diff --git a/backend/controller/dal/lease_test.go b/backend/controller/dal/lease_test.go index 0c6531cec6..9e2370d72f 100644 --- a/backend/controller/dal/lease_test.go +++ b/backend/controller/dal/lease_test.go @@ -36,7 +36,7 @@ func TestLease(t *testing.T) { } ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) // TTL is too short, expect an error @@ -71,7 +71,7 @@ func TestExpireLeases(t *testing.T) { } ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, NoOpEncryptors()) + dal, err := New(ctx, conn, optional.None[string]()) assert.NoError(t, err) leasei, _, err := dal.AcquireLease(ctx, leases.SystemKey("test"), time.Second*5, optional.None[any]()) diff --git a/backend/controller/dal/pubsub.go b/backend/controller/dal/pubsub.go index 6672482627..aed6077479 100644 --- a/backend/controller/dal/pubsub.go +++ b/backend/controller/dal/pubsub.go @@ -2,7 +2,6 @@ package dal import ( "context" - "encoding/json" "fmt" "strings" "time" @@ -14,6 +13,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" dalerrs "github.com/TBD54566975/ftl/backend/dal" "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/model" "github.com/TBD54566975/ftl/internal/rpc" @@ -21,7 +21,7 @@ import ( ) func (d *DAL) PublishEventForTopic(ctx context.Context, module, topic, caller string, payload []byte) error { - encryptedPayload, err := d.encryptors.Async.EncryptJSON(json.RawMessage(payload)) + encryptedPayload, err := d.encrypt(encryption.AsyncSubKey, payload) if err != nil { return fmt.Errorf("failed to encrypt payload: %w", err) } diff --git a/backend/controller/sql/migrate/migrate.go b/backend/controller/sql/migrate/migrate.go index d2e44d95b8..57f8522e9d 100644 --- a/backend/controller/sql/migrate/migrate.go +++ b/backend/controller/sql/migrate/migrate.go @@ -38,7 +38,7 @@ func Migration(version, name string, migration MigrationFunc) Option { } } -// LogLevel sets the loggging level of the migrator. +// LogLevel sets the logging level of the migrator. func LogLevel(level log.Level) Option { return func(opts *migrateOptions) { opts.logLevel = level diff --git a/backend/controller/sql/models.go b/backend/controller/sql/models.go index 5b5c1c76e4..731679ea0f 100644 --- a/backend/controller/sql/models.go +++ b/backend/controller/sql/models.go @@ -378,8 +378,8 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request json.RawMessage - Response pqtype.NullRawMessage + Request []byte + Response []byte Error optional.Option[string] RemainingAttempts int32 Backoff sqltypes.Duration @@ -429,6 +429,12 @@ type DeploymentArtefact struct { Path string } +type EncryptionKey struct { + ID int64 + Key []byte + CreatedAt time.Time +} + type Event struct { ID int64 TimeStamp time.Time diff --git a/backend/controller/sql/querier.go b/backend/controller/sql/querier.go index 42fc740ffe..b1d5c20460 100644 --- a/backend/controller/sql/querier.go +++ b/backend/controller/sql/querier.go @@ -32,6 +32,7 @@ type Querier interface { CreateCronJob(ctx context.Context, arg CreateCronJobParams) error CreateDeployment(ctx context.Context, moduleName string, schema []byte, key model.DeploymentKey) error CreateIngressRoute(ctx context.Context, arg CreateIngressRouteParams) error + CreateOnlyEncryptionKey(ctx context.Context, key []byte) error CreateRequest(ctx context.Context, origin Origin, key model.RequestKey, sourceAddr string) error DeleteOldEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) DeleteSubscribers(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriberKey, error) @@ -71,6 +72,7 @@ type Querier interface { GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) GetModulesByID(ctx context.Context, ids []int64) ([]Module, error) GetNextEventForSubscription(ctx context.Context, consumptionDelay sqltypes.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) + GetOnlyEncryptionKey(ctx context.Context) ([]byte, error) GetProcessList(ctx context.Context) ([]GetProcessListRow, error) GetRandomSubscriber(ctx context.Context, key model.SubscriptionKey) (GetRandomSubscriberRow, error) // Retrieve routing information for a runner. @@ -111,7 +113,7 @@ type Querier interface { // // "key" is the unique identifier for the FSM execution. StartFSMTransition(ctx context.Context, arg StartFSMTransitionParams) (FsmInstance, error) - SucceedAsyncCall(ctx context.Context, response json.RawMessage, iD int64) (bool, error) + SucceedAsyncCall(ctx context.Context, response []byte, iD int64) (bool, error) SucceedFSMInstance(ctx context.Context, fsm schema.RefKey, key string) (bool, error) UpsertController(ctx context.Context, key model.ControllerKey, endpoint string) (int64, error) UpsertModule(ctx context.Context, language string, name string) (int64, error) diff --git a/backend/controller/sql/queries.sql b/backend/controller/sql/queries.sql index 10854ad72e..cd98b31a89 100644 --- a/backend/controller/sql/queries.sql +++ b/backend/controller/sql/queries.sql @@ -542,7 +542,7 @@ RETURNING UPDATE async_calls SET state = 'success'::async_call_state, - response = @response::JSONB, + response = @response, error = null WHERE id = @id RETURNING true; @@ -878,3 +878,12 @@ WHERE id = $1::BIGINT; SELECT * FROM topic_events WHERE id = $1::BIGINT; + +-- name: GetOnlyEncryptionKey :one +SELECT key +FROM encryption_keys +WHERE id = 1; + +-- name: CreateOnlyEncryptionKey :exec +INSERT INTO encryption_keys (id, key) +VALUES (1, $1); diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index 77ed4654a6..fb7f4f10bd 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -67,7 +67,7 @@ type AcquireAsyncCallRow struct { Origin string Verb schema.RefKey CatchVerb optional.Option[schema.RefKey] - Request json.RawMessage + Request []byte ScheduledAt time.Time RemainingAttempts int32 Error optional.Option[string] @@ -216,7 +216,7 @@ RETURNING id type CreateAsyncCallParams struct { Verb schema.RefKey Origin string - Request json.RawMessage + Request []byte RemainingAttempts int32 Backoff sqltypes.Duration MaxBackoff sqltypes.Duration @@ -311,6 +311,16 @@ func (q *Queries) CreateIngressRoute(ctx context.Context, arg CreateIngressRoute return err } +const createOnlyEncryptionKey = `-- name: CreateOnlyEncryptionKey :exec +INSERT INTO encryption_keys (id, key) +VALUES (1, $1) +` + +func (q *Queries) CreateOnlyEncryptionKey(ctx context.Context, key []byte) error { + _, err := q.db.ExecContext(ctx, createOnlyEncryptionKey, key) + return err +} + const createRequest = `-- name: CreateRequest :exec INSERT INTO requests (origin, "key", source_addr) VALUES ($1, $2, $3) @@ -1452,6 +1462,19 @@ func (q *Queries) GetNextEventForSubscription(ctx context.Context, consumptionDe return i, err } +const getOnlyEncryptionKey = `-- name: GetOnlyEncryptionKey :one +SELECT key +FROM encryption_keys +WHERE id = 1 +` + +func (q *Queries) GetOnlyEncryptionKey(ctx context.Context) ([]byte, error) { + row := q.db.QueryRowContext(ctx, getOnlyEncryptionKey) + var key []byte + err := row.Scan(&key) + return key, err +} + const getProcessList = `-- name: GetProcessList :many SELECT d.min_replicas, d.key AS deployment_key, @@ -2550,13 +2573,13 @@ const succeedAsyncCall = `-- name: SucceedAsyncCall :one UPDATE async_calls SET state = 'success'::async_call_state, - response = $1::JSONB, + response = $1, error = null WHERE id = $2 RETURNING true ` -func (q *Queries) SucceedAsyncCall(ctx context.Context, response json.RawMessage, iD int64) (bool, error) { +func (q *Queries) SucceedAsyncCall(ctx context.Context, response []byte, iD int64) (bool, error) { row := q.db.QueryRowContext(ctx, succeedAsyncCall, response, iD) var column_1 bool err := row.Scan(&column_1) diff --git a/backend/controller/sql/schema/20240812011321_derive_encryption.sql b/backend/controller/sql/schema/20240812011321_derive_encryption.sql new file mode 100644 index 0000000000..bdb8b23962 --- /dev/null +++ b/backend/controller/sql/schema/20240812011321_derive_encryption.sql @@ -0,0 +1,19 @@ +-- migrate:up + +CREATE TABLE encryption_keys ( + id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + key bytea NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc') +); + +ALTER TABLE events + ALTER COLUMN payload TYPE bytea + USING payload::text::bytea; + +ALTER TABLE async_calls + ALTER COLUMN request TYPE bytea + USING request::text::bytea, + ALTER COLUMN response TYPE bytea + USING response::text::bytea; + +-- migrate:down diff --git a/cmd/ftl-controller/main.go b/cmd/ftl-controller/main.go index 20c4fa5f5e..83c2e88a46 100644 --- a/cmd/ftl-controller/main.go +++ b/cmd/ftl-controller/main.go @@ -9,6 +9,7 @@ import ( "github.com/XSAM/otelsql" "github.com/alecthomas/kong" + "github.com/alecthomas/types/optional" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -44,8 +45,9 @@ func main() { ) cli.ControllerConfig.SetDefaults() - encryptors, err := cli.ControllerConfig.EncryptionKeys.Encryptors(true) - kctx.FatalIfErrorf(err, "failed to create encryptors") + if cli.ControllerConfig.KMSURI == nil { + kctx.Fatalf("KMSURI is required") + } ctx := log.ContextWithLogger(context.Background(), log.Configure(os.Stderr, cli.LogConfig)) err = observability.Init(ctx, false, "", "ftl-controller", ftl.Version, cli.ObservabilityConfig) @@ -56,7 +58,7 @@ func main() { kctx.FatalIfErrorf(err) err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) kctx.FatalIfErrorf(err) - dal, err := dal.New(ctx, conn, encryptors) + dal, err := dal.New(ctx, conn, optional.Some[string](*cli.ControllerConfig.KMSURI)) kctx.FatalIfErrorf(err) configDal, err := cfdal.New(ctx, conn) @@ -77,6 +79,6 @@ func main() { kctx.FatalIfErrorf(err) ctx = cf.ContextWithSecrets(ctx, sm) - err = controller.Start(ctx, cli.ControllerConfig, scaling.NewK8sScaling(), conn, encryptors) + err = controller.Start(ctx, cli.ControllerConfig, scaling.NewK8sScaling(), conn) kctx.FatalIfErrorf(err) } diff --git a/cmd/ftl/cmd_box_run.go b/cmd/ftl/cmd_box_run.go index 541dd679a9..1fe6717591 100644 --- a/cmd/ftl/cmd_box_run.go +++ b/cmd/ftl/cmd_box_run.go @@ -67,14 +67,10 @@ func (b *boxRunCmd) Run(ctx context.Context, projConfig projectconfig.Config) er if err != nil { return fmt.Errorf("failed to register DB metrics: %w", err) } - encryptors, err := config.EncryptionKeys.Encryptors(false) - if err != nil { - return fmt.Errorf("failed to create encryptors: %w", err) - } wg := errgroup.Group{} wg.Go(func() error { - return controller.Start(ctx, config, runnerScaling, conn, encryptors) + return controller.Start(ctx, config, runnerScaling, conn) }) // Wait for the controller to come up. diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 5956677ceb..985181b913 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -148,7 +148,7 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini } controllerCtx = cf.ContextWithSecrets(controllerCtx, sm) - // Bring up the DB connection and DAL. + // Bring up the DB connection for the controller. conn, err := otelsql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) @@ -157,13 +157,9 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini if err != nil { return fmt.Errorf("failed to register DB metrics: %w", err) } - encryptors, err := config.EncryptionKeys.Encryptors(false) - if err != nil { - return fmt.Errorf("failed to create encryptors: %w", err) - } wg.Go(func() error { - if err := controller.Start(controllerCtx, config, runnerScaling, conn, encryptors); err != nil { + if err := controller.Start(controllerCtx, config, runnerScaling, conn); err != nil { logger.Errorf(err, "controller%d failed: %v", i, err) return fmt.Errorf("controller%d failed: %w", i, err) } diff --git a/common/configuration/sql/models.go b/common/configuration/sql/models.go index 5b5c1c76e4..731679ea0f 100644 --- a/common/configuration/sql/models.go +++ b/common/configuration/sql/models.go @@ -378,8 +378,8 @@ type AsyncCall struct { State AsyncCallState Origin string ScheduledAt time.Time - Request json.RawMessage - Response pqtype.NullRawMessage + Request []byte + Response []byte Error optional.Option[string] RemainingAttempts int32 Backoff sqltypes.Duration @@ -429,6 +429,12 @@ type DeploymentArtefact struct { Path string } +type EncryptionKey struct { + ID int64 + Key []byte + CreatedAt time.Time +} + type Event struct { ID int64 TimeStamp time.Time diff --git a/integration/harness.go b/integration/harness.go index aae96f7f13..5a9281ec55 100644 --- a/integration/harness.go +++ b/integration/harness.go @@ -77,11 +77,8 @@ func RunWithoutController(t *testing.T, ftlConfigPath string, actions ...Action) } func RunWithEncryption(t *testing.T, ftlConfigPath string, actions ...Action) { - logKey := `{"primaryKeyId":1467957621,"key":[{"keyData":{"typeUrl":"type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey","value":"Eg4IgIBAECAYAyIECAMQIBog7t16YRvohzTJBKt0D4WcqFpoeWH0C20Hr09v+AxbOOE=","keyMaterialType":"SYMMETRIC"},"status":"ENABLED","keyId":1467957621,"outputPrefixType":"RAW"}]}` - asyncKey := `{"primaryKeyId":2710864232,"key":[{"keyData":{"typeUrl":"type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey","value":"Eg4IgIBAECAYAyIECAMQIBogTFCSLcJGRRazu74LrehNGL82J0sicjnjG5uNZcDyjGE=","keyMaterialType":"SYMMETRIC"},"status":"ENABLED","keyId":2710864232,"outputPrefixType":"RAW"}]}` - - t.Setenv("FTL_LOG_ENCRYPTION_KEY", logKey) - t.Setenv("FTL_ASYNC_ENCRYPTION_KEY", asyncKey) + uri := "fake-kms://CKbvh_ILElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEE6tD2yE5AWYOirhmkY-r3sYARABGKbvh_ILIAE" + t.Setenv("FTL_KMS_URI", uri) run(t, ftlConfigPath, true, false, actions...) } diff --git a/internal/encryption/encryption.go b/internal/encryption/encryption.go index 59b1366e00..b6816e5986 100644 --- a/internal/encryption/encryption.go +++ b/internal/encryption/encryption.go @@ -2,177 +2,20 @@ package encryption import ( "bytes" - "encoding/json" "fmt" - "io" "strings" awsv1kms "github.com/aws/aws-sdk-go/service/kms" "github.com/tink-crypto/tink-go-awskms/integration/awskms" "github.com/tink-crypto/tink-go/v2/aead" "github.com/tink-crypto/tink-go/v2/core/registry" - "github.com/tink-crypto/tink-go/v2/insecurecleartextkeyset" "github.com/tink-crypto/tink-go/v2/keyderivation" "github.com/tink-crypto/tink-go/v2/keyset" "github.com/tink-crypto/tink-go/v2/prf" - "github.com/tink-crypto/tink-go/v2/streamingaead" "github.com/tink-crypto/tink-go/v2/testing/fakekms" "github.com/tink-crypto/tink-go/v2/tink" ) -// Encryptable is an interface for encrypting and decrypting JSON payloads. -// Deprecated: This is will be changed or removed very soon. -type Encryptable interface { - EncryptJSON(input any) (json.RawMessage, error) - DecryptJSON(input json.RawMessage, output any) error -} - -// NewForKeyOrURI creates a new encryptor using the provided key or URI. -// Deprecated: This is will be changed or removed very soon. -func NewForKeyOrURI(keyOrURI string) (Encryptable, error) { - if len(keyOrURI) == 0 { - return NoOpEncryptor{}, nil - } - - // If keyOrUri is a JSON string, it is a clear text key set. - if strings.TrimSpace(keyOrURI)[0] == '{' { - return NewClearTextEncryptor(keyOrURI) - // Otherwise should be a URI for KMS. - // aws-kms://arn:aws:kms:[region]:[account-id]:key/[key-id] - } else if strings.HasPrefix(keyOrURI, "aws-kms://") { - panic("not implemented") - } - return nil, fmt.Errorf("unsupported key or uri: %s", keyOrURI) -} - -// NoOpEncryptor does not encrypt or decrypt and just passes the input as is. -// Deprecated: This is will be changed or removed very soon. -type NoOpEncryptor struct { -} - -func (n NoOpEncryptor) EncryptJSON(input any) (json.RawMessage, error) { - msg, err := json.Marshal(input) - if err != nil { - return nil, fmt.Errorf("failed to marshal input: %w", err) - } - - return msg, nil -} - -func (n NoOpEncryptor) DecryptJSON(input json.RawMessage, output any) error { - err := json.Unmarshal(input, output) - if err != nil { - return fmt.Errorf("failed to unmarshal input: %w", err) - } - - return nil -} - -func NewClearTextEncryptor(key string) (Encryptable, error) { - keySetHandle, err := insecurecleartextkeyset.Read( - keyset.NewJSONReader(bytes.NewBufferString(key))) - if err != nil { - return nil, fmt.Errorf("failed to read clear text keyset: %w", err) - } - - encryptor, err := NewDeprecatedEncryptor(*keySetHandle) - if err != nil { - return nil, fmt.Errorf("failed to create clear text encryptor: %w", err) - } - - return encryptor, nil -} - -// NewDeprecatedEncryptor encrypts and decrypts JSON payloads using the provided key set. -// The key set must contain a primary key that is a streaming AEAD primitive. -func NewDeprecatedEncryptor(keySet keyset.Handle) (Encryptable, error) { - primitive, err := streamingaead.New(&keySet) - if err != nil { - return nil, fmt.Errorf("failed to create primitive during encryption: %w", err) - } - - return Encryptor{keySetHandle: keySet, primitive: primitive}, nil -} - -// Encryptor uses streaming with JSON payloads. -// Deprecated: This is will be changed or removed very soon. -type Encryptor struct { - keySetHandle keyset.Handle - primitive tink.StreamingAEAD -} - -// EncryptedPayload is a JSON payload that contains the encrypted data to put into the database. -// Deprecated: This is will be changed or removed very soon. -type EncryptedPayload struct { - Encrypted []byte `json:"encrypted"` -} - -func (e Encryptor) EncryptJSON(input any) (json.RawMessage, error) { - msg, err := json.Marshal(input) - if err != nil { - return nil, fmt.Errorf("failed to marshal input: %w", err) - } - - encrypted, err := encryptBytesForStreaming(e.primitive, msg) - if err != nil { - return nil, fmt.Errorf("failed to encrypt data: %w", err) - } - - out, err := json.Marshal(EncryptedPayload{Encrypted: encrypted}) - if err != nil { - return nil, fmt.Errorf("failed to marshal encrypted data: %w", err) - } - return out, nil -} - -func (e Encryptor) DecryptJSON(input json.RawMessage, output any) error { - var payload EncryptedPayload - if err := json.Unmarshal(input, &payload); err != nil { - return fmt.Errorf("failed to unmarshal encrypted payload: %w", err) - } - - decryptedBuffer, err := decryptBytesForStreaming(e.primitive, payload.Encrypted) - if err != nil { - return fmt.Errorf("failed to decrypt data: %w", err) - } - - if err := json.Unmarshal(decryptedBuffer, output); err != nil { - return fmt.Errorf("failed to unmarshal decrypted data: %w", err) - } - - return nil -} - -func encryptBytesForStreaming(streamingPrimitive tink.StreamingAEAD, clearText []byte) ([]byte, error) { - encryptedBuffer := &bytes.Buffer{} - msgBuffer := bytes.NewBuffer(clearText) - writer, err := streamingPrimitive.NewEncryptingWriter(encryptedBuffer, nil) - if err != nil { - return nil, fmt.Errorf("failed to create encrypting writer: %w", err) - } - if _, err := io.Copy(writer, msgBuffer); err != nil { - return nil, fmt.Errorf("failed to copy encrypted data: %w", err) - } - if err := writer.Close(); err != nil { - return nil, fmt.Errorf("failed to close encrypted writer: %w", err) - } - - return encryptedBuffer.Bytes(), nil -} - -func decryptBytesForStreaming(streamingPrimitive tink.StreamingAEAD, encrypted []byte) ([]byte, error) { - encryptedBuffer := bytes.NewReader(encrypted) - decryptedBuffer := &bytes.Buffer{} - reader, err := streamingPrimitive.NewDecryptingReader(encryptedBuffer, nil) - if err != nil { - return nil, fmt.Errorf("failed to create decrypting reader: %w", err) - } - if _, err := io.Copy(decryptedBuffer, reader); err != nil { - return nil, fmt.Errorf("failed to copy decrypted data: %w", err) - } - return decryptedBuffer.Bytes(), nil -} - type SubKey string const ( @@ -180,7 +23,7 @@ const ( AsyncSubKey SubKey = "async" ) -type EncryptorNext interface { +type DataEncryptor interface { Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) } @@ -188,6 +31,10 @@ type EncryptorNext interface { // NoOpEncryptorNext does not encrypt and just passes the input as is. type NoOpEncryptorNext struct{} +func NewNoOpEncryptor() NoOpEncryptorNext { + return NoOpEncryptorNext{} +} + func (n NoOpEncryptorNext) Encrypt(_ SubKey, cleartext []byte) ([]byte, error) { return cleartext, nil } @@ -196,44 +43,12 @@ func (n NoOpEncryptorNext) Decrypt(_ SubKey, encrypted []byte) ([]byte, error) { return encrypted, nil } -type PlaintextEncryptor struct { - root keyset.Handle -} - -func NewPlaintextEncryptor(key string) (*PlaintextEncryptor, error) { - handle, err := insecurecleartextkeyset.Read( - keyset.NewJSONReader(bytes.NewBufferString(key))) - if err != nil { - return nil, fmt.Errorf("failed to read clear text keyset: %w", err) - } - - return &PlaintextEncryptor{root: *handle}, nil -} - -func (p PlaintextEncryptor) Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) { - encrypted, err := derivedEncrypt(p.root, subKey, cleartext) - if err != nil { - return nil, fmt.Errorf("failed to encrypt with derive: %w", err) - } - - return encrypted, nil -} - -func (p PlaintextEncryptor) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) { - decrypted, err := derivedDecrypt(p.root, subKey, encrypted) - if err != nil { - return nil, fmt.Errorf("failed to decrypt with derive: %w", err) - } - - return decrypted, nil -} - // KMSEncryptor encrypts and decrypts using a KMS key via tink. -// TODO: maybe change to DerivableEncryptor and integrate plaintext and kms encryptor. type KMSEncryptor struct { root keyset.Handle kekAEAD tink.AEAD encryptedKeyset []byte + cachedDerived map[SubKey]tink.AEAD } func newClientWithAEAD(uri string, kms *awsv1kms.KMS) (tink.AEAD, error) { @@ -302,6 +117,7 @@ func NewKMSEncryptorGenerateKey(uri string, v1client *awsv1kms.KMS) (*KMSEncrypt root: *handle, kekAEAD: kekAEAD, encryptedKeyset: encryptedKeyset, + cachedDerived: make(map[SubKey]tink.AEAD), }, nil } @@ -321,6 +137,7 @@ func NewKMSEncryptorWithKMS(uri string, v1client *awsv1kms.KMS, encryptedKeyset root: *handle, kekAEAD: kekAEAD, encryptedKeyset: encryptedKeyset, + cachedDerived: make(map[SubKey]tink.AEAD), }, nil } @@ -342,26 +159,12 @@ func deriveKeyset(root keyset.Handle, salt []byte) (*keyset.Handle, error) { return derived, nil } -func (k *KMSEncryptor) Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) { - encrypted, err := derivedEncrypt(k.root, subKey, cleartext) - if err != nil { - return nil, fmt.Errorf("failed to encrypt with derive: %w", err) +func (k *KMSEncryptor) getDerivedPrimitive(subKey SubKey) (tink.AEAD, error) { + if primitive, ok := k.cachedDerived[subKey]; ok { + return primitive, nil } - return encrypted, nil -} - -func (k *KMSEncryptor) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) { - decrypted, err := derivedDecrypt(k.root, subKey, encrypted) - if err != nil { - return nil, fmt.Errorf("failed to decrypt with derive: %w", err) - } - - return decrypted, nil -} - -func derivedDecrypt(root keyset.Handle, subKey SubKey, encrypted []byte) ([]byte, error) { - derived, err := deriveKeyset(root, []byte(subKey)) + derived, err := deriveKeyset(k.root, []byte(subKey)) if err != nil { return nil, fmt.Errorf("failed to derive keyset: %w", err) } @@ -371,30 +174,34 @@ func derivedDecrypt(root keyset.Handle, subKey SubKey, encrypted []byte) ([]byte return nil, fmt.Errorf("failed to create primitive: %w", err) } - bytes, err := primitive.Decrypt(encrypted, nil) + k.cachedDerived[subKey] = primitive + return primitive, nil +} + +func (k *KMSEncryptor) Encrypt(subKey SubKey, cleartext []byte) ([]byte, error) { + primitive, err := k.getDerivedPrimitive(subKey) if err != nil { - return nil, fmt.Errorf("failed to decrypt: %w", err) + return nil, fmt.Errorf("failed to get derived primitive: %w", err) } - return bytes, nil -} - -func derivedEncrypt(root keyset.Handle, subKey SubKey, cleartext []byte) ([]byte, error) { - // TODO: Deriving might be expensive, consider caching the derived keyset. - derived, err := deriveKeyset(root, []byte(subKey)) + encrypted, err := primitive.Encrypt(cleartext, nil) if err != nil { - return nil, fmt.Errorf("failed to derive keyset: %w", err) + return nil, fmt.Errorf("failed to encrypt: %w", err) } - primitive, err := aead.New(derived) + return encrypted, nil +} + +func (k *KMSEncryptor) Decrypt(subKey SubKey, encrypted []byte) ([]byte, error) { + primitive, err := k.getDerivedPrimitive(subKey) if err != nil { - return nil, fmt.Errorf("failed to create primitive: %w", err) + return nil, fmt.Errorf("failed to get derived primitive: %w", err) } - bytes, err := primitive.Encrypt(cleartext, nil) + decrypted, err := primitive.Decrypt(encrypted, nil) if err != nil { - return nil, fmt.Errorf("failed to encrypt: %w", err) + return nil, fmt.Errorf("failed to decrypt: %w", err) } - return bytes, nil + return decrypted, nil } diff --git a/internal/encryption/encryption_test.go b/internal/encryption/encryption_test.go index 84542d39a9..f13e4358d5 100644 --- a/internal/encryption/encryption_test.go +++ b/internal/encryption/encryption_test.go @@ -1,73 +1,11 @@ package encryption import ( - "encoding/json" - "fmt" "testing" "github.com/alecthomas/assert/v2" ) -const streamingKey = `{ - "primaryKeyId": 1720777699, - "key": [{ - "keyData": { - "typeUrl": "type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey", - "keyMaterialType": "SYMMETRIC", - "value": "Eg0IgCAQIBgDIgQIAxAgGiDtesd/4gCnQdTrh+AXodwpm2b6BFJkp043n+8mqx0YGw==" - }, - "outputPrefixType": "RAW", - "keyId": 1720777699, - "status": "ENABLED" - }] -}` - -func TestDeprecatedNewEncryptor(t *testing.T) { - jsonInput := "\"hello\"" - - encryptor, err := NewForKeyOrURI(streamingKey) - assert.NoError(t, err) - - encrypted, err := encryptor.EncryptJSON(jsonInput) - assert.NoError(t, err) - fmt.Printf("Encrypted: %s\n", encrypted) - - var decrypted json.RawMessage - err = encryptor.DecryptJSON(encrypted, &decrypted) - assert.NoError(t, err) - fmt.Printf("Decrypted: %s\n", decrypted) - - var decryptedString string - err = json.Unmarshal(decrypted, &decryptedString) - assert.NoError(t, err) - fmt.Printf("Decrypted string: %s\n", decryptedString) - - assert.Equal(t, jsonInput, decryptedString) -} - -// tinkey create-keyset --key-template HKDF_SHA256_DERIVES_AES256_GCM -const key = `{"primaryKeyId":2304101620,"key":[{"keyData":{"typeUrl":"type.googleapis.com/google.crypto.tink.PrfBasedDeriverKey","value":"El0KMXR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLmNyeXB0by50aW5rLkhrZGZQcmZLZXkSJhICCAMaIDnEx9gPgeF32LQYjFYNSZe8b9KUl41Xy6to8MqKcSjBGAEaOgo4CjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNHY21LZXkSAhAgGAE=","keyMaterialType":"SYMMETRIC"},"status":"ENABLED","keyId":2304101620,"outputPrefixType":"TINK"}]}` - -func TestPlaintextEncryptor(t *testing.T) { - encryptor, err := NewPlaintextEncryptor(key) - assert.NoError(t, err) - - encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) - assert.NoError(t, err) - fmt.Printf("Encrypted: %s\n", encrypted) - - decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) - assert.NoError(t, err) - fmt.Printf("Decrypted: %s\n", decrypted) - - assert.Equal(t, "hunter2", string(decrypted)) - - // Should fail to decrypt with the wrong subkey - _, err = encryptor.Decrypt(AsyncSubKey, encrypted) - assert.Error(t, err) - -} - func TestNoOpEncryptor(t *testing.T) { encryptor := NoOpEncryptorNext{} @@ -80,8 +18,9 @@ func TestNoOpEncryptor(t *testing.T) { assert.Equal(t, "hunter2", string(decrypted)) } +// echo -n "fake-kms://" && tinkey create-keyset --key-template AES128_GCM --out-format binary | base64 | tr '+/' '-_' | tr -d '=' func TestKMSEncryptorFakeKMS(t *testing.T) { - uri := "fake-kms://CM2b3_MDElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEIK75t5L-adlUwVhWvRuWUwYARABGM2b3_MDIAE" + uri := "fake-kms://CKbvh_ILElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEE6tD2yE5AWYOirhmkY-r3sYARABGKbvh_ILIAE" encryptor, err := NewKMSEncryptorGenerateKey(uri, nil) assert.NoError(t, err) diff --git a/internal/encryption/integration_test.go b/internal/encryption/integration_test.go index bef904c8bb..92cca64ad0 100644 --- a/internal/encryption/integration_test.go +++ b/internal/encryption/integration_test.go @@ -55,13 +55,12 @@ func TestEncryptionForLogs(t *testing.T) { values := in.GetRow(t, ic, "ftl", "SELECT payload FROM events WHERE type = 'call' LIMIT 1", 1) payload, ok := values[0].([]byte) assert.True(t, ok, "could not convert payload to string") - assert.Contains(t, string(payload), "encrypted", "raw request string should not be stored in the table") assert.NotContains(t, string(payload), "Alice", "raw request string should not be stored in the table") }, ) } -func TestEncryptionForubSub(t *testing.T) { +func TestEncryptionForPubSub(t *testing.T) { in.RunWithEncryption(t, "", in.CopyModule("encryption"), in.Deploy("encryption"), @@ -75,7 +74,6 @@ func TestEncryptionForubSub(t *testing.T) { values := in.GetRow(t, ic, "ftl", "SELECT payload FROM topic_events", 1) payload, ok := values[0].([]byte) assert.True(t, ok, "could not convert payload to string") - assert.Contains(t, string(payload), "encrypted", "raw request string should not be stored in the table") assert.NotContains(t, string(payload), "AliceInWonderland", "raw request string should not be stored in the table") }, validateAsyncCall("consume", "AliceInWonderland"), @@ -103,7 +101,6 @@ func validateAsyncCall(verb string, sensitive string) in.Action { values := in.GetRow(t, ic, "ftl", fmt.Sprintf("SELECT request FROM async_calls WHERE verb = 'encryption.%s' AND state = 'success'", verb), 1) request, ok := values[0].([]byte) assert.True(t, ok, "could not convert payload to string") - assert.Contains(t, string(request), "encrypted", "raw request string should not be stored in the table") assert.NotContains(t, string(request), sensitive, "raw request string should not be stored in the table") } } From 2ab778b0ce964298189ae4b89784c52d6c9dcbea Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 14 Aug 2024 14:51:53 +1000 Subject: [PATCH 31/35] ci: run integration tests if the PR is labelled with "run-integration" (#2353) The label must be added as the PR is being created, not afterwards. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eed1614d74..774e2e95f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -179,7 +179,7 @@ jobs: - run: cd docs && zola build integration-shard: name: Shard Integration Tests - if: github.event_name != 'pull_request' || github.event.action == 'enqueued' + if: github.event_name != 'pull_request' || github.event.action == 'enqueued' || contains( github.event.pull_request.labels.*.name, 'run-integration') runs-on: ubuntu-latest outputs: matrix: ${{ steps.extract-tests.outputs.matrix }} @@ -195,7 +195,7 @@ jobs: echo "matrix={\"test\":$(jq -c -n '$ARGS.positional' --args $(git grep -l '^//go:build integration' | xargs grep '^func Test' | awk '{print $2}' | cut -d'(' -f1))}" >> "$GITHUB_OUTPUT" integration-run: name: Integration Test - if: github.event_name != 'pull_request' || github.event.action == 'enqueued' + if: github.event_name != 'pull_request' || github.event.action == 'enqueued' || contains( github.event.pull_request.labels.*.name, 'run-integration') needs: integration-shard runs-on: ubuntu-latest strategy: From 306b548395ef5b227bd6a89a2e8873d5c7ef8174 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 14 Aug 2024 18:04:02 +1000 Subject: [PATCH 32/35] fix: rename some timeline related names (#2355) 1. Renamed the "events" table to "timeline" to more clearly reflect its purpose and usage. 2. Renamed the encryption key from "logs" to "timeline" as the events table contains more than just logs. This just makes things a bit clearer. --- backend/controller/console/console.go | 10 +- backend/controller/cronjobs/sql/models.go | 28 +-- backend/controller/dal/dal.go | 18 +- backend/controller/dal/dal_test.go | 26 +-- backend/controller/dal/events.go | 44 ++-- backend/controller/sql/models.go | 28 +-- backend/controller/sql/querier.go | 12 +- backend/controller/sql/queries.sql | 36 ++-- backend/controller/sql/queries.sql.go | 192 +++++++++--------- ...240814060154_rename_events_to_timeline.sql | 6 + common/configuration/sql/models.go | 28 +-- internal/encryption/encryption.go | 4 +- internal/encryption/encryption_test.go | 8 +- internal/encryption/integration_test.go | 8 +- 14 files changed, 227 insertions(+), 221 deletions(-) create mode 100644 backend/controller/sql/schema/20240814060154_rename_events_to_timeline.sql diff --git a/backend/controller/console/console.go b/backend/controller/console/console.go index 23cbd9d3d2..67d9ea296b 100644 --- a/backend/controller/console/console.go +++ b/backend/controller/console/console.go @@ -195,7 +195,7 @@ func (c *ConsoleService) GetEvents(ctx context.Context, req *connect.Request[pbc // Get 1 more than the requested limit to determine if there are more results. limitPlusOne := limit + 1 - results, err := c.dal.QueryEvents(ctx, limitPlusOne, query...) + results, err := c.dal.QueryTimeline(ctx, limitPlusOne, query...) if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (c *ConsoleService) StreamEvents(ctx context.Context, req *connect.Request[ newQuery = append(newQuery, dal.FilterTimeRange(thisRequestTime, lastEventTime)) } - events, err := c.dal.QueryEvents(ctx, int(req.Msg.Query.Limit), newQuery...) + events, err := c.dal.QueryTimeline(ctx, int(req.Msg.Query.Limit), newQuery...) if err != nil { return err } @@ -264,8 +264,8 @@ func (c *ConsoleService) StreamEvents(ctx context.Context, req *connect.Request[ } } -func eventsQueryProtoToDAL(pb *pbconsole.EventsQuery) ([]dal.EventFilter, error) { - var query []dal.EventFilter +func eventsQueryProtoToDAL(pb *pbconsole.EventsQuery) ([]dal.TimelineFilter, error) { + var query []dal.TimelineFilter if pb.Order == pbconsole.EventsQuery_DESC { query = append(query, dal.FilterDescending()) @@ -357,7 +357,7 @@ func eventsQueryProtoToDAL(pb *pbconsole.EventsQuery) ([]dal.EventFilter, error) return query, nil } -func eventDALToProto(event dal.Event) *pbconsole.Event { +func eventDALToProto(event dal.TimelineEvent) *pbconsole.Event { switch event := event.(type) { case *dal.CallEvent: var requestKey *string diff --git a/backend/controller/cronjobs/sql/models.go b/backend/controller/cronjobs/sql/models.go index 731679ea0f..5c2780936a 100644 --- a/backend/controller/cronjobs/sql/models.go +++ b/backend/controller/cronjobs/sql/models.go @@ -435,20 +435,6 @@ type EncryptionKey struct { CreatedAt time.Time } -type Event struct { - ID int64 - TimeStamp time.Time - DeploymentID int64 - RequestID optional.Option[int64] - Type EventType - CustomKey1 optional.Option[string] - CustomKey2 optional.Option[string] - CustomKey3 optional.Option[string] - CustomKey4 optional.Option[string] - Payload json.RawMessage - ParentRequestID optional.Option[string] -} - type FsmInstance struct { ID int64 CreatedAt time.Time @@ -520,6 +506,20 @@ type Runner struct { Labels json.RawMessage } +type Timeline struct { + ID int64 + TimeStamp time.Time + DeploymentID int64 + RequestID optional.Option[int64] + Type EventType + CustomKey1 optional.Option[string] + CustomKey2 optional.Option[string] + CustomKey3 optional.Option[string] + CustomKey4 optional.Option[string] + Payload []byte + ParentRequestID optional.Option[string] +} + type Topic struct { ID int64 Key model.TopicKey diff --git a/backend/controller/dal/dal.go b/backend/controller/dal/dal.go index 9e1f7b4ac1..7172fe71dc 100644 --- a/backend/controller/dal/dal.go +++ b/backend/controller/dal/dal.go @@ -709,14 +709,14 @@ func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey return dalerrs.TranslatePGError(err) } } - payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]interface{}{ + payload, err := d.encryptJSON(encryption.TimelineSubKey, map[string]interface{}{ "prev_min_replicas": deployment.MinReplicas, "min_replicas": minReplicas, }) if err != nil { return fmt.Errorf("failed to encrypt payload for InsertDeploymentUpdatedEvent: %w", err) } - err = tx.InsertDeploymentUpdatedEvent(ctx, sql.InsertDeploymentUpdatedEventParams{ + err = tx.InsertTimelineDeploymentUpdatedEvent(ctx, sql.InsertTimelineDeploymentUpdatedEventParams{ DeploymentKey: key, Payload: payload, }) @@ -782,7 +782,7 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl } } - payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]any{ + payload, err := d.encryptJSON(encryption.TimelineSubKey, map[string]any{ "min_replicas": int32(minReplicas), "replaced": replacedDeploymentKey, }) @@ -790,7 +790,7 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl return fmt.Errorf("replace deployment failed to encrypt payload: %w", err) } - err = tx.InsertDeploymentCreatedEvent(ctx, sql.InsertDeploymentCreatedEventParams{ + err = tx.InsertTimelineDeploymentCreatedEvent(ctx, sql.InsertTimelineDeploymentCreatedEventParams{ DeploymentKey: newDeploymentKey, Language: newDeployment.Language, ModuleName: newDeployment.ModuleName, @@ -1057,11 +1057,11 @@ func (d *DAL) InsertLogEvent(ctx context.Context, log *LogEvent) error { "error": log.Error, "stack": log.Stack, } - encryptedPayload, err := d.encryptJSON(encryption.LogsSubKey, payload) + encryptedPayload, err := d.encryptJSON(encryption.TimelineSubKey, payload) if err != nil { return fmt.Errorf("failed to encrypt log payload: %w", err) } - return dalerrs.TranslatePGError(d.db.InsertLogEvent(ctx, sql.InsertLogEventParams{ + return dalerrs.TranslatePGError(d.db.InsertTimelineLogEvent(ctx, sql.InsertTimelineLogEventParams{ DeploymentKey: log.DeploymentKey, RequestKey: requestKey, TimeStamp: log.Time, @@ -1137,7 +1137,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { if pr, ok := call.ParentRequestKey.Get(); ok { parentRequestKey = optional.Some(pr.String()) } - payload, err := d.encryptJSON(encryption.LogsSubKey, map[string]any{ + payload, err := d.encryptJSON(encryption.TimelineSubKey, map[string]any{ "duration_ms": call.Duration.Milliseconds(), "request": call.Request, "response": call.Response, @@ -1147,7 +1147,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { if err != nil { return fmt.Errorf("failed to encrypt call payload: %w", err) } - return dalerrs.TranslatePGError(d.db.InsertCallEvent(ctx, sql.InsertCallEventParams{ + return dalerrs.TranslatePGError(d.db.InsertTimelineCallEvent(ctx, sql.InsertTimelineCallEventParams{ DeploymentKey: call.DeploymentKey, RequestKey: requestKey, ParentRequestKey: parentRequestKey, @@ -1161,7 +1161,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { } func (d *DAL) DeleteOldEvents(ctx context.Context, eventType EventType, age time.Duration) (int64, error) { - count, err := d.db.DeleteOldEvents(ctx, sqltypes.Duration(age), eventType) + count, err := d.db.DeleteOldTimelineEvents(ctx, sqltypes.Duration(age), eventType) return count, dalerrs.TranslatePGError(err) } diff --git a/backend/controller/dal/dal_test.go b/backend/controller/dal/dal_test.go index ee3618c442..43ed5e9c4c 100644 --- a/backend/controller/dal/dal_test.go +++ b/backend/controller/dal/dal_test.go @@ -263,39 +263,39 @@ func TestDAL(t *testing.T) { t.Run("QueryEvents", func(t *testing.T) { t.Run("Limit", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1) + events, err := dal.QueryTimeline(ctx, 1) assert.NoError(t, err) assert.Equal(t, 1, len(events)) }) t.Run("NoFilters", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1000) + events, err := dal.QueryTimeline(ctx, 1000) assert.NoError(t, err) - assertEventsEqual(t, []Event{expectedDeploymentUpdatedEvent, callEvent, logEvent}, events) + assertEventsEqual(t, []TimelineEvent{expectedDeploymentUpdatedEvent, callEvent, logEvent}, events) }) t.Run("ByDeployment", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1000, FilterDeployments(deploymentKey)) + events, err := dal.QueryTimeline(ctx, 1000, FilterDeployments(deploymentKey)) assert.NoError(t, err) - assertEventsEqual(t, []Event{expectedDeploymentUpdatedEvent, callEvent, logEvent}, events) + assertEventsEqual(t, []TimelineEvent{expectedDeploymentUpdatedEvent, callEvent, logEvent}, events) }) t.Run("ByCall", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1000, FilterTypes(EventTypeCall), FilterCall(optional.None[string](), "time", optional.None[string]())) + events, err := dal.QueryTimeline(ctx, 1000, FilterTypes(EventTypeCall), FilterCall(optional.None[string](), "time", optional.None[string]())) assert.NoError(t, err) - assertEventsEqual(t, []Event{callEvent}, events) + assertEventsEqual(t, []TimelineEvent{callEvent}, events) }) t.Run("ByLogLevel", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1000, FilterTypes(EventTypeLog), FilterLogLevel(log.Trace)) + events, err := dal.QueryTimeline(ctx, 1000, FilterTypes(EventTypeLog), FilterLogLevel(log.Trace)) assert.NoError(t, err) - assertEventsEqual(t, []Event{logEvent}, events) + assertEventsEqual(t, []TimelineEvent{logEvent}, events) }) t.Run("ByRequests", func(t *testing.T) { - events, err := dal.QueryEvents(ctx, 1000, FilterRequests(requestKey)) + events, err := dal.QueryTimeline(ctx, 1000, FilterRequests(requestKey)) assert.NoError(t, err) - assertEventsEqual(t, []Event{callEvent, logEvent}, events) + assertEventsEqual(t, []TimelineEvent{callEvent, logEvent}, events) }) }) @@ -386,7 +386,7 @@ func TestRunnerStateFromProto(t *testing.T) { assert.Equal(t, RunnerStateIdle, RunnerStateFromProto(state)) } -func normaliseEvents(events []Event) []Event { +func normaliseEvents(events []TimelineEvent) []TimelineEvent { for i := range len(events) { event := events[i] re := reflect.Indirect(reflect.ValueOf(event)) @@ -400,7 +400,7 @@ func normaliseEvents(events []Event) []Event { return events } -func assertEventsEqual(t *testing.T, expected, actual []Event) { +func assertEventsEqual(t *testing.T, expected, actual []TimelineEvent) { t.Helper() assert.Equal(t, normaliseEvents(expected), normaliseEvents(actual)) } diff --git a/backend/controller/dal/events.go b/backend/controller/dal/events.go index 75babd7fe4..1ae4282b11 100644 --- a/backend/controller/dal/events.go +++ b/backend/controller/dal/events.go @@ -28,10 +28,10 @@ const ( EventTypeDeploymentUpdated = sql.EventTypeDeploymentUpdated ) -// Event types. +// TimelineEvent types. // //sumtype:decl -type Event interface { +type TimelineEvent interface { GetID() int64 event() } @@ -112,9 +112,9 @@ type eventFilter struct { descending bool } -type EventFilter func(query *eventFilter) +type TimelineFilter func(query *eventFilter) -func FilterLogLevel(level log.Level) EventFilter { +func FilterLogLevel(level log.Level) TimelineFilter { return func(query *eventFilter) { query.level = &level } @@ -123,19 +123,19 @@ func FilterLogLevel(level log.Level) EventFilter { // FilterCall filters call events between the given modules. // // May be called multiple times. -func FilterCall(sourceModule optional.Option[string], destModule string, destVerb optional.Option[string]) EventFilter { +func FilterCall(sourceModule optional.Option[string], destModule string, destVerb optional.Option[string]) TimelineFilter { return func(query *eventFilter) { query.calls = append(query.calls, &eventFilterCall{sourceModule: sourceModule, destModule: destModule, destVerb: destVerb}) } } -func FilterDeployments(deploymentKeys ...model.DeploymentKey) EventFilter { +func FilterDeployments(deploymentKeys ...model.DeploymentKey) TimelineFilter { return func(query *eventFilter) { query.deployments = append(query.deployments, deploymentKeys...) } } -func FilterRequests(requestKeys ...model.RequestKey) EventFilter { +func FilterRequests(requestKeys ...model.RequestKey) TimelineFilter { return func(query *eventFilter) { for _, request := range requestKeys { query.requests = append(query.requests, request.String()) @@ -143,7 +143,7 @@ func FilterRequests(requestKeys ...model.RequestKey) EventFilter { } } -func FilterTypes(types ...sql.EventType) EventFilter { +func FilterTypes(types ...sql.EventType) TimelineFilter { return func(query *eventFilter) { query.types = append(query.types, types...) } @@ -152,7 +152,7 @@ func FilterTypes(types ...sql.EventType) EventFilter { // FilterTimeRange filters events between the given times, inclusive. // // Either maybe be zero to indicate no upper or lower bound. -func FilterTimeRange(olderThan, newerThan time.Time) EventFilter { +func FilterTimeRange(olderThan, newerThan time.Time) TimelineFilter { return func(query *eventFilter) { query.newerThan = newerThan query.olderThan = olderThan @@ -160,7 +160,7 @@ func FilterTimeRange(olderThan, newerThan time.Time) EventFilter { } // FilterIDRange filters events between the given IDs, inclusive. -func FilterIDRange(higherThan, lowerThan int64) EventFilter { +func FilterIDRange(higherThan, lowerThan int64) TimelineFilter { return func(query *eventFilter) { query.idHigherThan = higherThan query.idLowerThan = lowerThan @@ -168,7 +168,7 @@ func FilterIDRange(higherThan, lowerThan int64) EventFilter { } // FilterDescending returns events in descending order. -func FilterDescending() EventFilter { +func FilterDescending() TimelineFilter { return func(query *eventFilter) { query.descending = true } @@ -201,12 +201,12 @@ type eventDeploymentUpdatedJSON struct { } type eventRow struct { - sql.Event + sql.Timeline DeploymentKey model.DeploymentKey RequestKey optional.Option[model.RequestKey] } -func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter) ([]Event, error) { +func (d *DAL) QueryTimeline(ctx context.Context, limit int, filters ...TimelineFilter) ([]TimelineEvent, error) { if limit < 1 { return nil, fmt.Errorf("limit must be >= 1, got %d", limit) } @@ -222,7 +222,7 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter e.custom_key_4, e.type, e.payload - FROM events e + FROM timeline e LEFT JOIN requests ir on e.request_id = ir.id WHERE true -- The "true" is to simplify the ANDs below. ` @@ -256,7 +256,7 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter deploymentArgs := []any{} if len(filter.deployments) != 0 { // Unfortunately, if we use a join here, PG will do a sequential scan on - // events and deployments, making a 7ms query into a 700ms query. + // timeline and deployments, making a 7ms query into a 700ms query. // https://www.pgexplain.dev/plan/ecd44488-6060-4ad1-a9b4-49d092c3de81 deploymentQuery += ` WHERE key = ANY($1::TEXT[])` deploymentArgs = append(deploymentArgs, filter.deployments) @@ -323,15 +323,15 @@ func (d *DAL) QueryEvents(ctx context.Context, limit int, filters ...EventFilter } defer rows.Close() - events, err := d.transformRowsToEvents(deploymentKeys, rows) + events, err := d.transformRowsToTimelineEvents(deploymentKeys, rows) if err != nil { return nil, err } return events, nil } -func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey, rows *stdsql.Rows) ([]Event, error) { - var out []Event +func (d *DAL) transformRowsToTimelineEvents(deploymentKeys map[int64]model.DeploymentKey, rows *stdsql.Rows) ([]TimelineEvent, error) { + var out []TimelineEvent for rows.Next() { row := eventRow{} var deploymentID int64 @@ -349,7 +349,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey switch row.Type { case sql.EventTypeLog: var jsonPayload eventLogJSON - if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.TimelineSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt log event: %w", err) } @@ -371,7 +371,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeCall: var jsonPayload eventCallJSON - if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.TimelineSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } var sourceVerb optional.Option[schema.Ref] @@ -396,7 +396,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeDeploymentCreated: var jsonPayload eventDeploymentCreatedJSON - if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.TimelineSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } out = append(out, &DeploymentCreatedEvent{ @@ -411,7 +411,7 @@ func (d *DAL) transformRowsToEvents(deploymentKeys map[int64]model.DeploymentKey case sql.EventTypeDeploymentUpdated: var jsonPayload eventDeploymentUpdatedJSON - if err := d.decryptJSON(encryption.LogsSubKey, row.Payload, &jsonPayload); err != nil { + if err := d.decryptJSON(encryption.TimelineSubKey, row.Payload, &jsonPayload); err != nil { return nil, fmt.Errorf("failed to decrypt call event: %w", err) } out = append(out, &DeploymentUpdatedEvent{ diff --git a/backend/controller/sql/models.go b/backend/controller/sql/models.go index 731679ea0f..5c2780936a 100644 --- a/backend/controller/sql/models.go +++ b/backend/controller/sql/models.go @@ -435,20 +435,6 @@ type EncryptionKey struct { CreatedAt time.Time } -type Event struct { - ID int64 - TimeStamp time.Time - DeploymentID int64 - RequestID optional.Option[int64] - Type EventType - CustomKey1 optional.Option[string] - CustomKey2 optional.Option[string] - CustomKey3 optional.Option[string] - CustomKey4 optional.Option[string] - Payload json.RawMessage - ParentRequestID optional.Option[string] -} - type FsmInstance struct { ID int64 CreatedAt time.Time @@ -520,6 +506,20 @@ type Runner struct { Labels json.RawMessage } +type Timeline struct { + ID int64 + TimeStamp time.Time + DeploymentID int64 + RequestID optional.Option[int64] + Type EventType + CustomKey1 optional.Option[string] + CustomKey2 optional.Option[string] + CustomKey3 optional.Option[string] + CustomKey4 optional.Option[string] + Payload []byte + ParentRequestID optional.Option[string] +} + type Topic struct { ID int64 Key model.TopicKey diff --git a/backend/controller/sql/querier.go b/backend/controller/sql/querier.go index b1d5c20460..0f2602688a 100644 --- a/backend/controller/sql/querier.go +++ b/backend/controller/sql/querier.go @@ -34,7 +34,7 @@ type Querier interface { CreateIngressRoute(ctx context.Context, arg CreateIngressRouteParams) error CreateOnlyEncryptionKey(ctx context.Context, key []byte) error CreateRequest(ctx context.Context, origin Origin, key model.RequestKey, sourceAddr string) error - DeleteOldEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) + DeleteOldTimelineEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) DeleteSubscribers(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriberKey, error) DeleteSubscriptions(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriptionKey, error) DeregisterRunner(ctx context.Context, key model.RunnerKey) (int64, error) @@ -90,12 +90,12 @@ type Querier interface { GetSubscriptionsNeedingUpdate(ctx context.Context) ([]GetSubscriptionsNeedingUpdateRow, error) GetTopic(ctx context.Context, dollar_1 int64) (Topic, error) GetTopicEvent(ctx context.Context, dollar_1 int64) (TopicEvent, error) - InsertCallEvent(ctx context.Context, arg InsertCallEventParams) error - InsertDeploymentCreatedEvent(ctx context.Context, arg InsertDeploymentCreatedEventParams) error - InsertDeploymentUpdatedEvent(ctx context.Context, arg InsertDeploymentUpdatedEventParams) error - InsertEvent(ctx context.Context, arg InsertEventParams) error - InsertLogEvent(ctx context.Context, arg InsertLogEventParams) error InsertSubscriber(ctx context.Context, arg InsertSubscriberParams) error + InsertTimelineCallEvent(ctx context.Context, arg InsertTimelineCallEventParams) error + InsertTimelineDeploymentCreatedEvent(ctx context.Context, arg InsertTimelineDeploymentCreatedEventParams) error + InsertTimelineDeploymentUpdatedEvent(ctx context.Context, arg InsertTimelineDeploymentUpdatedEventParams) error + InsertTimelineEvent(ctx context.Context, arg InsertTimelineEventParams) error + InsertTimelineLogEvent(ctx context.Context, arg InsertTimelineLogEventParams) error // Mark any controller entries that haven't been updated recently as dead. KillStaleControllers(ctx context.Context, timeout sqltypes.Duration) (int64, error) KillStaleRunners(ctx context.Context, timeout sqltypes.Duration) (int64, error) diff --git a/backend/controller/sql/queries.sql b/backend/controller/sql/queries.sql index cd98b31a89..386d180fba 100644 --- a/backend/controller/sql/queries.sql +++ b/backend/controller/sql/queries.sql @@ -270,8 +270,8 @@ WITH rows AS ( SELECT COUNT(*) FROM rows; --- name: InsertLogEvent :exec -INSERT INTO events ( +-- name: InsertTimelineLogEvent :exec +INSERT INTO timeline ( deployment_id, request_id, time_stamp, @@ -293,8 +293,8 @@ VALUES ( sqlc.arg('payload') ); --- name: InsertDeploymentCreatedEvent :exec -INSERT INTO events ( +-- name: InsertTimelineDeploymentCreatedEvent :exec +INSERT INTO timeline ( deployment_id, type, custom_key_1, @@ -302,7 +302,7 @@ INSERT INTO events ( payload ) VALUES ( - ( + ( SELECT id FROM deployments WHERE deployments.key = sqlc.arg('deployment_key')::deployment_key @@ -313,8 +313,8 @@ VALUES ( sqlc.arg('payload') ); --- name: InsertDeploymentUpdatedEvent :exec -INSERT INTO events ( +-- name: InsertTimelineDeploymentUpdatedEvent :exec +INSERT INTO timeline ( deployment_id, type, custom_key_1, @@ -333,8 +333,8 @@ VALUES ( sqlc.arg('payload') ); --- name: InsertCallEvent :exec -INSERT INTO events ( +-- name: InsertTimelineCallEvent :exec +INSERT INTO timeline ( deployment_id, request_id, parent_request_id, @@ -365,9 +365,9 @@ VALUES ( sqlc.arg('payload') ); --- name: DeleteOldEvents :one +-- name: DeleteOldTimelineEvents :one WITH deleted AS ( - DELETE FROM events + DELETE FROM timeline WHERE time_stamp < (NOW() AT TIME ZONE 'utc') - sqlc.arg('timeout')::INTERVAL AND type = sqlc.arg('type') RETURNING 1 @@ -423,8 +423,8 @@ FROM ingress_routes ir WHERE d.min_replicas > 0; --- name: InsertEvent :exec -INSERT INTO events (deployment_id, request_id, parent_request_id, type, +-- name: InsertTimelineEvent :exec +INSERT INTO timeline (deployment_id, request_id, parent_request_id, type, custom_key_1, custom_key_2, custom_key_3, custom_key_4, payload) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) @@ -667,8 +667,8 @@ VALUES ( sqlc.arg('name')::TEXT, sqlc.arg('event_type')::TEXT ) -ON CONFLICT (name, module_id) DO -UPDATE SET +ON CONFLICT (name, module_id) DO +UPDATE SET type = sqlc.arg('event_type')::TEXT RETURNING id; @@ -693,12 +693,12 @@ VALUES ( sqlc.arg('name')::TEXT ) ON CONFLICT (name, module_id) DO -UPDATE SET +UPDATE SET topic_id = excluded.topic_id, deployment_id = (SELECT id FROM deployments WHERE key = sqlc.arg('deployment')::deployment_key) -RETURNING +RETURNING id, - CASE + CASE WHEN xmax = 0 THEN true ELSE false END AS inserted; diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index fb7f4f10bd..79b2a680dd 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -331,9 +331,9 @@ func (q *Queries) CreateRequest(ctx context.Context, origin Origin, key model.Re return err } -const deleteOldEvents = `-- name: DeleteOldEvents :one +const deleteOldTimelineEvents = `-- name: DeleteOldTimelineEvents :one WITH deleted AS ( - DELETE FROM events + DELETE FROM timeline WHERE time_stamp < (NOW() AT TIME ZONE 'utc') - $1::INTERVAL AND type = $2 RETURNING 1 @@ -342,8 +342,8 @@ SELECT COUNT(*) FROM deleted ` -func (q *Queries) DeleteOldEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) { - row := q.db.QueryRowContext(ctx, deleteOldEvents, timeout, type_) +func (q *Queries) DeleteOldTimelineEvents(ctx context.Context, timeout sqltypes.Duration, type_ EventType) (int64, error) { + row := q.db.QueryRowContext(ctx, deleteOldTimelineEvents, timeout, type_) var count int64 err := row.Scan(&count) return count, err @@ -1945,8 +1945,64 @@ func (q *Queries) GetTopicEvent(ctx context.Context, dollar_1 int64) (TopicEvent return i, err } -const insertCallEvent = `-- name: InsertCallEvent :exec -INSERT INTO events ( +const insertSubscriber = `-- name: InsertSubscriber :exec +INSERT INTO topic_subscribers ( + key, + topic_subscriptions_id, + deployment_id, + sink, + retry_attempts, + backoff, + max_backoff, + catch_verb +) +VALUES ( + $1::subscriber_key, + ( + SELECT topic_subscriptions.id as id + FROM topic_subscriptions + INNER JOIN modules ON topic_subscriptions.module_id = modules.id + WHERE modules.name = $2::TEXT + AND topic_subscriptions.name = $3::TEXT + ), + (SELECT id FROM deployments WHERE key = $4::deployment_key), + $5, + $6, + $7::interval, + $8::interval, + $9 +) +` + +type InsertSubscriberParams struct { + Key model.SubscriberKey + Module string + SubscriptionName string + Deployment model.DeploymentKey + Sink schema.RefKey + RetryAttempts int32 + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration + CatchVerb optional.Option[schema.RefKey] +} + +func (q *Queries) InsertSubscriber(ctx context.Context, arg InsertSubscriberParams) error { + _, err := q.db.ExecContext(ctx, insertSubscriber, + arg.Key, + arg.Module, + arg.SubscriptionName, + arg.Deployment, + arg.Sink, + arg.RetryAttempts, + arg.Backoff, + arg.MaxBackoff, + arg.CatchVerb, + ) + return err +} + +const insertTimelineCallEvent = `-- name: InsertTimelineCallEvent :exec +INSERT INTO timeline ( deployment_id, request_id, parent_request_id, @@ -1978,7 +2034,7 @@ VALUES ( ) ` -type InsertCallEventParams struct { +type InsertTimelineCallEventParams struct { DeploymentKey model.DeploymentKey RequestKey optional.Option[string] ParentRequestKey optional.Option[string] @@ -1987,11 +2043,11 @@ type InsertCallEventParams struct { SourceVerb optional.Option[string] DestModule string DestVerb string - Payload json.RawMessage + Payload []byte } -func (q *Queries) InsertCallEvent(ctx context.Context, arg InsertCallEventParams) error { - _, err := q.db.ExecContext(ctx, insertCallEvent, +func (q *Queries) InsertTimelineCallEvent(ctx context.Context, arg InsertTimelineCallEventParams) error { + _, err := q.db.ExecContext(ctx, insertTimelineCallEvent, arg.DeploymentKey, arg.RequestKey, arg.ParentRequestKey, @@ -2005,8 +2061,8 @@ func (q *Queries) InsertCallEvent(ctx context.Context, arg InsertCallEventParams return err } -const insertDeploymentCreatedEvent = `-- name: InsertDeploymentCreatedEvent :exec -INSERT INTO events ( +const insertTimelineDeploymentCreatedEvent = `-- name: InsertTimelineDeploymentCreatedEvent :exec +INSERT INTO timeline ( deployment_id, type, custom_key_1, @@ -2014,7 +2070,7 @@ INSERT INTO events ( payload ) VALUES ( - ( + ( SELECT id FROM deployments WHERE deployments.key = $1::deployment_key @@ -2026,15 +2082,15 @@ VALUES ( ) ` -type InsertDeploymentCreatedEventParams struct { +type InsertTimelineDeploymentCreatedEventParams struct { DeploymentKey model.DeploymentKey Language string ModuleName string - Payload json.RawMessage + Payload []byte } -func (q *Queries) InsertDeploymentCreatedEvent(ctx context.Context, arg InsertDeploymentCreatedEventParams) error { - _, err := q.db.ExecContext(ctx, insertDeploymentCreatedEvent, +func (q *Queries) InsertTimelineDeploymentCreatedEvent(ctx context.Context, arg InsertTimelineDeploymentCreatedEventParams) error { + _, err := q.db.ExecContext(ctx, insertTimelineDeploymentCreatedEvent, arg.DeploymentKey, arg.Language, arg.ModuleName, @@ -2043,8 +2099,8 @@ func (q *Queries) InsertDeploymentCreatedEvent(ctx context.Context, arg InsertDe return err } -const insertDeploymentUpdatedEvent = `-- name: InsertDeploymentUpdatedEvent :exec -INSERT INTO events ( +const insertTimelineDeploymentUpdatedEvent = `-- name: InsertTimelineDeploymentUpdatedEvent :exec +INSERT INTO timeline ( deployment_id, type, custom_key_1, @@ -2064,15 +2120,15 @@ VALUES ( ) ` -type InsertDeploymentUpdatedEventParams struct { +type InsertTimelineDeploymentUpdatedEventParams struct { DeploymentKey model.DeploymentKey Language string ModuleName string - Payload json.RawMessage + Payload []byte } -func (q *Queries) InsertDeploymentUpdatedEvent(ctx context.Context, arg InsertDeploymentUpdatedEventParams) error { - _, err := q.db.ExecContext(ctx, insertDeploymentUpdatedEvent, +func (q *Queries) InsertTimelineDeploymentUpdatedEvent(ctx context.Context, arg InsertTimelineDeploymentUpdatedEventParams) error { + _, err := q.db.ExecContext(ctx, insertTimelineDeploymentUpdatedEvent, arg.DeploymentKey, arg.Language, arg.ModuleName, @@ -2081,15 +2137,15 @@ func (q *Queries) InsertDeploymentUpdatedEvent(ctx context.Context, arg InsertDe return err } -const insertEvent = `-- name: InsertEvent :exec -INSERT INTO events (deployment_id, request_id, parent_request_id, type, +const insertTimelineEvent = `-- name: InsertTimelineEvent :exec +INSERT INTO timeline (deployment_id, request_id, parent_request_id, type, custom_key_1, custom_key_2, custom_key_3, custom_key_4, payload) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id ` -type InsertEventParams struct { +type InsertTimelineEventParams struct { DeploymentID int64 RequestID optional.Option[int64] ParentRequestID optional.Option[string] @@ -2098,11 +2154,11 @@ type InsertEventParams struct { CustomKey2 optional.Option[string] CustomKey3 optional.Option[string] CustomKey4 optional.Option[string] - Payload json.RawMessage + Payload []byte } -func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) error { - _, err := q.db.ExecContext(ctx, insertEvent, +func (q *Queries) InsertTimelineEvent(ctx context.Context, arg InsertTimelineEventParams) error { + _, err := q.db.ExecContext(ctx, insertTimelineEvent, arg.DeploymentID, arg.RequestID, arg.ParentRequestID, @@ -2116,8 +2172,8 @@ func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) error return err } -const insertLogEvent = `-- name: InsertLogEvent :exec -INSERT INTO events ( +const insertTimelineLogEvent = `-- name: InsertTimelineLogEvent :exec +INSERT INTO timeline ( deployment_id, request_id, time_stamp, @@ -2140,16 +2196,16 @@ VALUES ( ) ` -type InsertLogEventParams struct { +type InsertTimelineLogEventParams struct { DeploymentKey model.DeploymentKey RequestKey optional.Option[string] TimeStamp time.Time Level int32 - Payload json.RawMessage + Payload []byte } -func (q *Queries) InsertLogEvent(ctx context.Context, arg InsertLogEventParams) error { - _, err := q.db.ExecContext(ctx, insertLogEvent, +func (q *Queries) InsertTimelineLogEvent(ctx context.Context, arg InsertTimelineLogEventParams) error { + _, err := q.db.ExecContext(ctx, insertTimelineLogEvent, arg.DeploymentKey, arg.RequestKey, arg.TimeStamp, @@ -2159,62 +2215,6 @@ func (q *Queries) InsertLogEvent(ctx context.Context, arg InsertLogEventParams) return err } -const insertSubscriber = `-- name: InsertSubscriber :exec -INSERT INTO topic_subscribers ( - key, - topic_subscriptions_id, - deployment_id, - sink, - retry_attempts, - backoff, - max_backoff, - catch_verb -) -VALUES ( - $1::subscriber_key, - ( - SELECT topic_subscriptions.id as id - FROM topic_subscriptions - INNER JOIN modules ON topic_subscriptions.module_id = modules.id - WHERE modules.name = $2::TEXT - AND topic_subscriptions.name = $3::TEXT - ), - (SELECT id FROM deployments WHERE key = $4::deployment_key), - $5, - $6, - $7::interval, - $8::interval, - $9 -) -` - -type InsertSubscriberParams struct { - Key model.SubscriberKey - Module string - SubscriptionName string - Deployment model.DeploymentKey - Sink schema.RefKey - RetryAttempts int32 - Backoff sqltypes.Duration - MaxBackoff sqltypes.Duration - CatchVerb optional.Option[schema.RefKey] -} - -func (q *Queries) InsertSubscriber(ctx context.Context, arg InsertSubscriberParams) error { - _, err := q.db.ExecContext(ctx, insertSubscriber, - arg.Key, - arg.Module, - arg.SubscriptionName, - arg.Deployment, - arg.Sink, - arg.RetryAttempts, - arg.Backoff, - arg.MaxBackoff, - arg.CatchVerb, - ) - return err -} - const killStaleControllers = `-- name: KillStaleControllers :one WITH matches AS ( UPDATE controller @@ -2708,12 +2708,12 @@ VALUES ( $6::TEXT ) ON CONFLICT (name, module_id) DO -UPDATE SET +UPDATE SET topic_id = excluded.topic_id, deployment_id = (SELECT id FROM deployments WHERE key = $5::deployment_key) -RETURNING +RETURNING id, - CASE + CASE WHEN xmax = 0 THEN true ELSE false END AS inserted @@ -2755,8 +2755,8 @@ VALUES ( $3::TEXT, $4::TEXT ) -ON CONFLICT (name, module_id) DO -UPDATE SET +ON CONFLICT (name, module_id) DO +UPDATE SET type = $4::TEXT RETURNING id ` diff --git a/backend/controller/sql/schema/20240814060154_rename_events_to_timeline.sql b/backend/controller/sql/schema/20240814060154_rename_events_to_timeline.sql new file mode 100644 index 0000000000..579ed8faa9 --- /dev/null +++ b/backend/controller/sql/schema/20240814060154_rename_events_to_timeline.sql @@ -0,0 +1,6 @@ +-- migrate:up + +ALTER TABLE events RENAME TO timeline; + +-- migrate:down + diff --git a/common/configuration/sql/models.go b/common/configuration/sql/models.go index 731679ea0f..5c2780936a 100644 --- a/common/configuration/sql/models.go +++ b/common/configuration/sql/models.go @@ -435,20 +435,6 @@ type EncryptionKey struct { CreatedAt time.Time } -type Event struct { - ID int64 - TimeStamp time.Time - DeploymentID int64 - RequestID optional.Option[int64] - Type EventType - CustomKey1 optional.Option[string] - CustomKey2 optional.Option[string] - CustomKey3 optional.Option[string] - CustomKey4 optional.Option[string] - Payload json.RawMessage - ParentRequestID optional.Option[string] -} - type FsmInstance struct { ID int64 CreatedAt time.Time @@ -520,6 +506,20 @@ type Runner struct { Labels json.RawMessage } +type Timeline struct { + ID int64 + TimeStamp time.Time + DeploymentID int64 + RequestID optional.Option[int64] + Type EventType + CustomKey1 optional.Option[string] + CustomKey2 optional.Option[string] + CustomKey3 optional.Option[string] + CustomKey4 optional.Option[string] + Payload []byte + ParentRequestID optional.Option[string] +} + type Topic struct { ID int64 Key model.TopicKey diff --git a/internal/encryption/encryption.go b/internal/encryption/encryption.go index b6816e5986..9815b846bc 100644 --- a/internal/encryption/encryption.go +++ b/internal/encryption/encryption.go @@ -19,8 +19,8 @@ import ( type SubKey string const ( - LogsSubKey SubKey = "logs" - AsyncSubKey SubKey = "async" + TimelineSubKey SubKey = "timeline" + AsyncSubKey SubKey = "async" ) type DataEncryptor interface { diff --git a/internal/encryption/encryption_test.go b/internal/encryption/encryption_test.go index f13e4358d5..b30719ff17 100644 --- a/internal/encryption/encryption_test.go +++ b/internal/encryption/encryption_test.go @@ -9,10 +9,10 @@ import ( func TestNoOpEncryptor(t *testing.T) { encryptor := NoOpEncryptorNext{} - encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + encrypted, err := encryptor.Encrypt(TimelineSubKey, []byte("hunter2")) assert.NoError(t, err) - decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + decrypted, err := encryptor.Decrypt(TimelineSubKey, encrypted) assert.NoError(t, err) assert.Equal(t, "hunter2", string(decrypted)) @@ -25,10 +25,10 @@ func TestKMSEncryptorFakeKMS(t *testing.T) { encryptor, err := NewKMSEncryptorGenerateKey(uri, nil) assert.NoError(t, err) - encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + encrypted, err := encryptor.Encrypt(TimelineSubKey, []byte("hunter2")) assert.NoError(t, err) - decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + decrypted, err := encryptor.Decrypt(TimelineSubKey, encrypted) assert.NoError(t, err) assert.Equal(t, "hunter2", string(decrypted)) diff --git a/internal/encryption/integration_test.go b/internal/encryption/integration_test.go index 92cca64ad0..4b0c35d50e 100644 --- a/internal/encryption/integration_test.go +++ b/internal/encryption/integration_test.go @@ -50,9 +50,9 @@ func TestEncryptionForLogs(t *testing.T) { }, // confirm that we can't find that raw request string in the table - in.QueryRow("ftl", "SELECT COUNT(*) FROM events WHERE type = 'call'", int64(1)), + in.QueryRow("ftl", "SELECT COUNT(*) FROM timeline WHERE type = 'call'", int64(1)), func(t testing.TB, ic in.TestContext) { - values := in.GetRow(t, ic, "ftl", "SELECT payload FROM events WHERE type = 'call' LIMIT 1", 1) + values := in.GetRow(t, ic, "ftl", "SELECT payload FROM timeline WHERE type = 'call' LIMIT 1", 1) payload, ok := values[0].([]byte) assert.True(t, ok, "could not convert payload to string") assert.NotContains(t, string(payload), "Alice", "raw request string should not be stored in the table") @@ -130,10 +130,10 @@ func TestKMSEncryptorLocalstack(t *testing.T) { encryptor, err := NewKMSEncryptorGenerateKey(uri, v1client) assert.NoError(t, err) - encrypted, err := encryptor.Encrypt(LogsSubKey, []byte("hunter2")) + encrypted, err := encryptor.Encrypt(TimelineSubKey, []byte("hunter2")) assert.NoError(t, err) - decrypted, err := encryptor.Decrypt(LogsSubKey, encrypted) + decrypted, err := encryptor.Decrypt(TimelineSubKey, encrypted) assert.NoError(t, err) assert.Equal(t, "hunter2", string(decrypted)) From 4a24b88a7549b6fc300cb123ac0ba50a6e847c79 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Wed, 14 Aug 2024 18:43:33 +1000 Subject: [PATCH 33/35] chore: update capability matrix (#2359) --- docs/content/docs/reference/matrix.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/docs/reference/matrix.md b/docs/content/docs/reference/matrix.md index 817281f7b4..12172bd4de 100644 --- a/docs/content/docs/reference/matrix.md +++ b/docs/content/docs/reference/matrix.md @@ -19,7 +19,7 @@ top = false | | Optional Type | ✔️ | ✔️ | | | | Unit Type | ✔️ | ✔️ | | | | Empty Type | ✔️ | ✔️ | | -| | Generic Types | ✔️ | ️ | | +| | Generic Types | ✔️ | ✔️ | | | | Type Aliases | ✔️ | ️ | | | | Value Enums | ✔️ | ️ | | | | Type Enums | ✔️ | ️ | | @@ -31,9 +31,9 @@ top = false | | Visibility | ✔️ | ✔️ | | | **Core** | FSM | ✔️ | ️ | | | | Leases | ✔️ | ✔️ | | -| | Cron | ✔️ | | | +| | Cron | ✔️ | ✔️ | | | | Config | ✔️ | ✔️ | | -| | Secrets | ✔️ | | | +| | Secrets | ✔️ | ✔️ | | | | HTTP Ingress | ✔️ | ✔️ | | | **Resources** | PostgreSQL | ✔️ | ️ | | | | MySQL | | | | From 71d6cf8f9f1f431115fed4d836840f84a0f38654 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Thu, 15 Aug 2024 01:50:16 +1000 Subject: [PATCH 34/35] refactor: extend the integration testing framework to support multiple languages (#2362) Previously we had full test coverage in each language, so we would just run them all, but as we're building up support for other languages for now, this change allows multiple languages to be supported per-test. Also cleans up the test harness so there's just a single Run() function whose behaviour can be configured. --- backend/controller/admin/local_client_test.go | 13 +- .../console/console_integration_test.go | 5 +- .../cronjobs/cronjobs_integration_test.go | 2 +- .../controller/dal/fsm_integration_test.go | 9 +- .../ingress/ingress_integration_test.go | 4 +- .../leases/lease_integration_test.go | 2 +- backend/controller/pubsub/integration_test.go | 8 +- .../sql/database_integration_test.go | 6 +- cmd/ftl/integration_test.go | 30 +-- common/projectconfig/integration_test.go | 13 +- .../compile/compile_integration_test.go | 8 +- .../encoding/encoding_integration_test.go | 5 +- go-runtime/ftl/ftl_integration_test.go | 11 +- .../ftl/ftltest/ftltest_integration_test.go | 4 +- go-runtime/ftl/integration_test.go | 2 +- .../reflection/reflection_integration_test.go | 2 +- go-runtime/internal/integration_test.go | 2 +- integration/actions.go | 11 +- integration/harness.go | 200 +++++++++++------- internal/encryption/integration_test.go | 13 +- java-runtime/java_integration_test.go | 3 +- 21 files changed, 221 insertions(+), 132 deletions(-) diff --git a/backend/controller/admin/local_client_test.go b/backend/controller/admin/local_client_test.go index 1d4f9eab4e..97e0a66e54 100644 --- a/backend/controller/admin/local_client_test.go +++ b/backend/controller/admin/local_client_test.go @@ -6,15 +6,18 @@ import ( "context" "testing" + "github.com/alecthomas/assert/v2" + "github.com/alecthomas/types/optional" + cf "github.com/TBD54566975/ftl/common/configuration" in "github.com/TBD54566975/ftl/integration" "github.com/TBD54566975/ftl/internal/log" - "github.com/alecthomas/assert/v2" - "github.com/alecthomas/types/optional" ) func TestDiskSchemaRetrieverWithBuildArtefact(t *testing.T) { - in.RunWithoutController(t, "ftl-project-dr.toml", + in.Run(t, + in.WithFTLConfig("ftl-project-dr.toml"), + in.WithoutController(), in.CopyModule("dischema"), in.Build("dischema"), func(t testing.TB, ic in.TestContext) { @@ -30,7 +33,9 @@ func TestDiskSchemaRetrieverWithBuildArtefact(t *testing.T) { } func TestDiskSchemaRetrieverWithNoSchema(t *testing.T) { - in.RunWithoutController(t, "ftl-project-dr.toml", + in.Run(t, + in.WithFTLConfig("ftl-project-dr.toml"), + in.WithoutController(), in.CopyModule("dischema"), func(t testing.TB, ic in.TestContext) { dsr := &diskSchemaRetriever{} diff --git a/backend/controller/console/console_integration_test.go b/backend/controller/console/console_integration_test.go index b3d1baa882..22513f3610 100644 --- a/backend/controller/console/console_integration_test.go +++ b/backend/controller/console/console_integration_test.go @@ -6,9 +6,10 @@ import ( "testing" "connectrpc.com/connect" + "github.com/alecthomas/assert/v2" + pbconsole "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/console" in "github.com/TBD54566975/ftl/integration" - "github.com/alecthomas/assert/v2" ) // GetModules calls console service GetModules and returns the response. @@ -24,7 +25,7 @@ func GetModules(onResponse func(t testing.TB, resp *connect.Response[pbconsole.G } func TestConsoleGetModules(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("console"), in.Deploy("console"), GetModules(func(t testing.TB, resp *connect.Response[pbconsole.GetModulesResponse]) { diff --git a/backend/controller/cronjobs/cronjobs_integration_test.go b/backend/controller/cronjobs/cronjobs_integration_test.go index 62d9984c5c..5824acbbf5 100644 --- a/backend/controller/cronjobs/cronjobs_integration_test.go +++ b/backend/controller/cronjobs/cronjobs_integration_test.go @@ -53,7 +53,7 @@ func TestCron(t *testing.T) { t.Cleanup(func() { _ = os.Remove(tmpFile) }) - in.Run(t, "", + in.Run(t, in.CopyModule("cron"), in.Deploy("cron"), func(t testing.TB, ic in.TestContext) { diff --git a/backend/controller/dal/fsm_integration_test.go b/backend/controller/dal/fsm_integration_test.go index 6ae5a00e83..2fee9701c3 100644 --- a/backend/controller/dal/fsm_integration_test.go +++ b/backend/controller/dal/fsm_integration_test.go @@ -8,8 +8,9 @@ import ( "testing" "time" - in "github.com/TBD54566975/ftl/integration" "github.com/alecthomas/assert/v2" + + in "github.com/TBD54566975/ftl/integration" ) func TestFSM(t *testing.T) { @@ -22,7 +23,7 @@ func TestFSM(t *testing.T) { WHERE fsm = 'fsm.fsm' AND key = '%s' `, instance), status, state) } - in.Run(t, "", + in.Run(t, in.CopyModule("fsm"), in.Deploy("fsm"), @@ -81,7 +82,7 @@ func TestFSMRetry(t *testing.T) { } } - in.Run(t, "", + in.Run(t, in.CopyModule("fsmretry"), in.Build("fsmretry"), in.Deploy("fsmretry"), @@ -127,7 +128,7 @@ func TestFSMRetry(t *testing.T) { func TestFSMGoTests(t *testing.T) { logFilePath := filepath.Join(t.TempDir(), "fsm.log") t.Setenv("FSM_LOG_FILE", logFilePath) - in.Run(t, "", + in.Run(t, in.CopyModule("fsm"), in.Build("fsm"), in.ExecModuleTest("fsm"), diff --git a/backend/controller/ingress/ingress_integration_test.go b/backend/controller/ingress/ingress_integration_test.go index e5474d314e..4679ce16a0 100644 --- a/backend/controller/ingress/ingress_integration_test.go +++ b/backend/controller/ingress/ingress_integration_test.go @@ -14,7 +14,7 @@ import ( ) func TestHttpIngress(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("httpingress"), in.Deploy("httpingress"), in.HttpCall(http.MethodGet, "/users/123/posts/456", nil, in.JsonData(t, in.Obj{}), func(t testing.TB, resp *in.HTTPResponse) { @@ -152,7 +152,7 @@ func TestHttpIngress(t *testing.T) { func TestHttpIngressWithCors(t *testing.T) { os.Setenv("FTL_CONTROLLER_ALLOW_ORIGIN", "http://localhost:8892") os.Setenv("FTL_CONTROLLER_ALLOW_HEADERS", "x-forwarded-capabilities") - in.Run(t, "", + in.Run(t, in.CopyModule("httpingress"), in.Deploy("httpingress"), // A correct CORS preflight request diff --git a/backend/controller/leases/lease_integration_test.go b/backend/controller/leases/lease_integration_test.go index 002fb62f64..3af001258c 100644 --- a/backend/controller/leases/lease_integration_test.go +++ b/backend/controller/leases/lease_integration_test.go @@ -18,7 +18,7 @@ import ( ) func TestLease(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("leases"), in.Build("leases"), // checks if leases work in a unit test environment diff --git a/backend/controller/pubsub/integration_test.go b/backend/controller/pubsub/integration_test.go index bc8dbdd0b9..879db011d1 100644 --- a/backend/controller/pubsub/integration_test.go +++ b/backend/controller/pubsub/integration_test.go @@ -15,7 +15,7 @@ import ( func TestPubSub(t *testing.T) { calls := 20 events := calls * 10 - in.Run(t, "", + in.Run(t, in.CopyModule("publisher"), in.CopyModule("subscriber"), in.Deploy("publisher"), @@ -40,7 +40,7 @@ func TestPubSub(t *testing.T) { } func TestConsumptionDelay(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("publisher"), in.CopyModule("subscriber"), in.Deploy("publisher"), @@ -83,7 +83,7 @@ func TestConsumptionDelay(t *testing.T) { func TestRetry(t *testing.T) { retriesPerCall := 2 - in.Run(t, "", + in.Run(t, in.CopyModule("publisher"), in.CopyModule("subscriber"), in.Deploy("publisher"), @@ -135,7 +135,7 @@ func TestRetry(t *testing.T) { } func TestExternalPublishRuntimeCheck(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("publisher"), in.CopyModule("subscriber"), in.Deploy("publisher"), diff --git a/backend/controller/sql/database_integration_test.go b/backend/controller/sql/database_integration_test.go index 57e355beb2..a82cdb84b1 100644 --- a/backend/controller/sql/database_integration_test.go +++ b/backend/controller/sql/database_integration_test.go @@ -10,7 +10,8 @@ import ( ) func TestDatabase(t *testing.T) { - in.Run(t, "database/ftl-project.toml", + in.Run(t, + in.WithFTLConfig("database/ftl-project.toml"), // deploy real module against "testdb" in.CopyModule("database"), in.CreateDBAction("database", "testdb", false), @@ -33,7 +34,8 @@ func TestMigrate(t *testing.T) { return in.QueryRow(dbName, "SELECT version FROM schema_migrations WHERE version = '20240704103403'", "20240704103403") } - in.RunWithoutController(t, "", + in.Run(t, + in.WithoutController(), in.DropDBAction(t, dbName), in.Fail(q(), "Should fail because the database does not exist."), in.Exec("ftl", "migrate", "--dsn", dbUri), diff --git a/cmd/ftl/integration_test.go b/cmd/ftl/integration_test.go index 015fa07e23..75b19e426e 100644 --- a/cmd/ftl/integration_test.go +++ b/cmd/ftl/integration_test.go @@ -24,7 +24,8 @@ func TestBox(t *testing.T) { ctx := log.ContextWithNewDefaultLogger(context.Background()) err := exec.Command(ctx, log.Debug, "../..", "docker", "build", "-t", "ftl0/ftl-box:latest", "--progress=plain", "--platform=linux/amd64", "-f", "Dockerfile.box", ".").Run() assert.NoError(t, err) - RunWithoutController(t, "", + Run(t, + WithoutController(), CopyModule("time"), CopyModule("echo"), Exec("ftl", "box", "echo", "--compose=echo-compose.yml"), @@ -35,17 +36,17 @@ func TestBox(t *testing.T) { } func TestConfigsWithController(t *testing.T) { - Run(t, "", configActions(t)...) + Run(t, configActions(t)...) } func TestConfigsWithoutController(t *testing.T) { - RunWithoutController(t, "", configActions(t)...) + Run(t, configActions(t, WithoutController())...) } -func configActions(t *testing.T) []Action { +func configActions(t *testing.T, prepend ...ActionOrOption) []ActionOrOption { t.Helper() - return []Action{ + return append(prepend, // test setting value without --json flag Exec("ftl", "config", "set", "test.one", "hello world", "--inline"), ExecWithExpectedOutput("\"hello world\"\n", "ftl", "config", "get", "test.one"), @@ -58,18 +59,18 @@ func configActions(t *testing.T) []Action { ExecWithOutput("ftl", []string{"config", "get", "test.one"}, func(output string) {}), "failed to get from config manager: not found", ), - } + ) } func TestSecretsWithController(t *testing.T) { - Run(t, "", secretActions(t)...) + Run(t, secretActions(t)...) } func TestSecretsWithoutController(t *testing.T) { - RunWithoutController(t, "", secretActions(t)...) + Run(t, secretActions(t, WithoutController())...) } -func secretActions(t *testing.T) []Action { +func secretActions(t *testing.T, prepend ...ActionOrOption) []ActionOrOption { t.Helper() // can not easily use Exec() to enter secure text, using secret import instead @@ -78,7 +79,7 @@ func secretActions(t *testing.T) []Action { secretsPath2, err := filepath.Abs("testdata/secrets2.json") assert.NoError(t, err) - return []Action{ + return append(prepend, // test setting secret without --json flag Exec("ftl", "secret", "import", "--inline", secretsPath1), ExecWithExpectedOutput("\"hello world\"\n", "ftl", "secret", "get", "test.one"), @@ -91,7 +92,7 @@ func secretActions(t *testing.T) []Action { ExecWithOutput("ftl", []string{"secret", "get", "test.one"}, func(output string) {}), "failed to get from secret manager: not found", ), - } + ) } func TestSecretImportExport(t *testing.T) { @@ -116,7 +117,8 @@ func testImportExport(t *testing.T, object string) { blank := "" exported := &blank - RunWithoutController(t, "", + Run(t, + WithoutController(), // duplicate project file in the temp directory Exec("cp", firstProjFile, secondProjFile), // import into first project file @@ -152,7 +154,7 @@ func NewFunction(ctx context.Context, req TimeRequest) (TimeResponse, error) { return TimeResponse{Time: time.Now()}, nil } ` - Run(t, "", + Run(t, CopyModule("time"), Deploy("time"), ExecWithOutput("ftl", []string{"schema", "diff"}, func(output string) { @@ -199,7 +201,7 @@ func TestResetSubscription(t *testing.T) { `, module, subscription), cursor) } - Run(t, "", + Run(t, CopyModule("time"), CopyModule("echo"), Deploy("time"), diff --git a/common/projectconfig/integration_test.go b/common/projectconfig/integration_test.go index 2e79d26e31..f7b46df8dc 100644 --- a/common/projectconfig/integration_test.go +++ b/common/projectconfig/integration_test.go @@ -14,7 +14,8 @@ import ( ) func TestDefaultToRootWhenModuleDirsMissing(t *testing.T) { - in.Run(t, "no-module-dirs-ftl-project.toml", + in.Run(t, + in.WithFTLConfig("no-module-dirs-ftl-project.toml"), in.CopyModule("echo"), in.Exec("ftl", "build"), // Needs to be `ftl build`, not `ftl build echo` in.Deploy("echo"), @@ -25,7 +26,9 @@ func TestDefaultToRootWhenModuleDirsMissing(t *testing.T) { } func TestConfigCmdWithoutController(t *testing.T) { - in.RunWithoutController(t, "configs-ftl-project.toml", + in.Run(t, + in.WithFTLConfig("configs-ftl-project.toml"), + in.WithoutController(), in.ExecWithExpectedOutput("\"value\"\n", "ftl", "config", "get", "key"), ) } @@ -49,7 +52,8 @@ func TestFindConfig(t *testing.T) { assert.Equal(t, "test = \"test\"\n", string(output)) } } - in.RunWithoutController(t, "", + in.Run(t, + in.WithoutController(), in.CopyModule("findconfig"), checkConfig("findconfig"), checkConfig("findconfig/subdir"), @@ -61,7 +65,8 @@ func TestFindConfig(t *testing.T) { } func TestConfigValidation(t *testing.T) { - in.Run(t, "./validateconfig/ftl-project.toml", + in.Run(t, + in.WithFTLConfig("./validateconfig/ftl-project.toml"), in.CopyModule("validateconfig"), // Global sets never error. diff --git a/go-runtime/compile/compile_integration_test.go b/go-runtime/compile/compile_integration_test.go index 567eca4cc3..23091bbfd4 100644 --- a/go-runtime/compile/compile_integration_test.go +++ b/go-runtime/compile/compile_integration_test.go @@ -12,7 +12,7 @@ import ( ) func TestNonExportedDecls(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("time"), in.Deploy("time"), in.CopyModule("echo"), @@ -26,7 +26,7 @@ func TestNonExportedDecls(t *testing.T) { } func TestUndefinedExportedDecls(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("time"), in.Deploy("time"), in.CopyModule("echo"), @@ -40,7 +40,7 @@ func TestUndefinedExportedDecls(t *testing.T) { } func TestNonFTLTypes(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("external"), in.Deploy("external"), in.Call("external", "echo", in.Obj{"message": "hello"}, func(t testing.TB, response in.Obj) { @@ -50,7 +50,7 @@ func TestNonFTLTypes(t *testing.T) { } func TestNonStructRequestResponse(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("two"), in.Deploy("two"), in.CopyModule("one"), diff --git a/go-runtime/encoding/encoding_integration_test.go b/go-runtime/encoding/encoding_integration_test.go index d8157ba364..35cfa1586e 100644 --- a/go-runtime/encoding/encoding_integration_test.go +++ b/go-runtime/encoding/encoding_integration_test.go @@ -6,12 +6,13 @@ import ( "net/http" "testing" - in "github.com/TBD54566975/ftl/integration" "github.com/alecthomas/assert/v2" + + in "github.com/TBD54566975/ftl/integration" ) func TestHttpEncodeOmitempty(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("omitempty"), in.Deploy("omitempty"), in.HttpCall(http.MethodGet, "/get", nil, in.JsonData(t, in.Obj{}), func(t testing.TB, resp *in.HTTPResponse) { diff --git a/go-runtime/ftl/ftl_integration_test.go b/go-runtime/ftl/ftl_integration_test.go index 06afc15ae5..1dff86c46d 100644 --- a/go-runtime/ftl/ftl_integration_test.go +++ b/go-runtime/ftl/ftl_integration_test.go @@ -6,14 +6,15 @@ import ( "strings" "testing" - in "github.com/TBD54566975/ftl/integration" "github.com/alecthomas/assert/v2" + in "github.com/TBD54566975/ftl/integration" + "github.com/alecthomas/repr" ) func TestLifecycle(t *testing.T) { - in.Run(t, "", + in.Run(t, in.GitInit(), in.Exec("rm", "ftl-project.toml"), in.Exec("ftl", "init", "test", "."), @@ -26,7 +27,7 @@ func TestLifecycle(t *testing.T) { } func TestInterModuleCall(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("echo"), in.CopyModule("time"), in.Deploy("time"), @@ -42,7 +43,7 @@ func TestInterModuleCall(t *testing.T) { } func TestSchemaGenerate(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyDir("../schema-generate", "schema-generate"), in.Mkdir("build/schema-generate"), in.Exec("ftl", "schema", "generate", "schema-generate", "build/schema-generate"), @@ -51,7 +52,7 @@ func TestSchemaGenerate(t *testing.T) { } func TestTypeRegistryUnitTest(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("typeregistry"), in.Deploy("typeregistry"), in.ExecModuleTest("typeregistry"), diff --git a/go-runtime/ftl/ftltest/ftltest_integration_test.go b/go-runtime/ftl/ftltest/ftltest_integration_test.go index d53a8cf0d8..5eb88500d6 100644 --- a/go-runtime/ftl/ftltest/ftltest_integration_test.go +++ b/go-runtime/ftl/ftltest/ftltest_integration_test.go @@ -9,7 +9,9 @@ import ( ) func TestModuleUnitTests(t *testing.T) { - in.RunWithoutController(t, "wrapped/ftl-project.toml", + in.Run(t, + in.WithFTLConfig("wrapped/ftl-project.toml"), + in.WithoutController(), in.GitInit(), in.CopyModule("time"), in.CopyModule("wrapped"), diff --git a/go-runtime/ftl/integration_test.go b/go-runtime/ftl/integration_test.go index 155156a76a..e96d0ff0f9 100644 --- a/go-runtime/ftl/integration_test.go +++ b/go-runtime/ftl/integration_test.go @@ -9,7 +9,7 @@ import ( ) func TestFTLMap(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("mapper"), in.Build("mapper"), in.ExecModuleTest("mapper"), diff --git a/go-runtime/ftl/reflection/reflection_integration_test.go b/go-runtime/ftl/reflection/reflection_integration_test.go index e858feefc3..c91c9fdef2 100644 --- a/go-runtime/ftl/reflection/reflection_integration_test.go +++ b/go-runtime/ftl/reflection/reflection_integration_test.go @@ -9,7 +9,7 @@ import ( ) func TestRuntimeReflection(t *testing.T) { - in.Run(t, "", + in.Run(t, in.CopyModule("runtimereflection"), in.ExecModuleTest("runtimereflection"), ) diff --git a/go-runtime/internal/integration_test.go b/go-runtime/internal/integration_test.go index 9c7f07b566..5f2bca228b 100644 --- a/go-runtime/internal/integration_test.go +++ b/go-runtime/internal/integration_test.go @@ -11,7 +11,7 @@ import ( ) func TestRealMap(t *testing.T) { - Run(t, "", + Run(t, CopyModule("mapper"), Deploy("mapper"), Call("mapper", "get", Obj{}, func(t testing.TB, response Obj) { diff --git a/integration/actions.go b/integration/actions.go index ebfe57d400..7875fd7429 100644 --- a/integration/actions.go +++ b/integration/actions.go @@ -51,13 +51,18 @@ func GitInit() Action { // Copy a module from the testdata directory to the working directory. // -// Ensures that replace directives are correctly handled. +// Ensures that any language-specific local modifications are made correctly, +// such as Go module file replace directives for FTL. func CopyModule(module string) Action { return Chain( CopyDir(module, module), func(t testing.TB, ic TestContext) { - err := ftlexec.Command(ic, log.Debug, filepath.Join(ic.workDir, module), "go", "mod", "edit", "-replace", "github.com/TBD54566975/ftl="+ic.RootDir).RunBuffered(ic) - assert.NoError(t, err) + root := filepath.Join(ic.workDir, module) + // TODO: Load the module configuration from the module itself and use that to determine the language-specific stuff. + if _, err := os.Stat(filepath.Join(root, "go.mod")); err == nil { + err := ftlexec.Command(ic, log.Debug, root, "go", "mod", "edit", "-replace", "github.com/TBD54566975/ftl="+ic.RootDir).RunBuffered(ic) + assert.NoError(t, err) + } }, ) } diff --git a/integration/harness.go b/integration/harness.go index 5a9281ec55..b9a192ecc2 100644 --- a/integration/harness.go +++ b/integration/harness.go @@ -43,47 +43,98 @@ func Infof(format string, args ...any) { var buildOnce sync.Once -// Run an integration test. -// ftlConfigPath: if FTL_CONFIG should be set for this test, then pass in the relative +// An Option for configuring the integration test harness. +type Option func(*options) + +// ActionOrOption is a type that can be either an Action or an Option. +type ActionOrOption any + +// WithLanguages is a Run* option that specifies the languages to test. // -// path based on ./testdata/go/ where "." denotes the directory containing the -// integration test (e.g. for "integration/harness_test.go" supplying -// "database/ftl-project.toml" would set FTL_CONFIG to -// "integration/testdata/go/database/ftl-project.toml"). -func Run(t *testing.T, ftlConfigPath string, actions ...Action) { - run(t, ftlConfigPath, true, false, actions...) +// Defaults to "go" if not provided. +func WithLanguages(languages ...string) Option { + return func(o *options) { + o.languages = languages + } } -// RunWithJava runs an integration test after building the Java runtime. -// ftlConfigPath: if FTL_CONFIG should be set for this test, then pass in the relative +// WithFTLConfig is a Run* option that specifies the FTL config to use. // -// path based on ./testdata/go/ where "." denotes the directory containing the -// integration test (e.g. for "integration/harness_test.go" supplying -// "database/ftl-project.toml" would set FTL_CONFIG to -// "integration/testdata/go/database/ftl-project.toml"). -func RunWithJava(t *testing.T, ftlConfigPath string, actions ...Action) { - run(t, ftlConfigPath, true, true, actions...) +// This will set FTL_CONFIG for this test, then pass in the relative +// path based on ./testdata/go/ where "." denotes the directory containing the +// integration test (e.g. for "integration/harness_test.go" supplying +// "database/ftl-project.toml" would set FTL_CONFIG to +// "integration/testdata/go/database/ftl-project.toml"). +func WithFTLConfig(path string) Option { + return func(o *options) { + o.ftlConfigPath = path + } } -// RunWithoutController runs an integration test without starting the controller. -// ftlConfigPath: if FTL_CONFIG should be set for this test, then pass in the relative -// -// path based on ./testdata/go/ where "." denotes the directory containing the -// integration test (e.g. for "integration/harness_test.go" supplying -// "database/ftl-project.toml" would set FTL_CONFIG to -// "integration/testdata/go/database/ftl-project.toml"). -func RunWithoutController(t *testing.T, ftlConfigPath string, actions ...Action) { - run(t, ftlConfigPath, false, false, actions...) +// WithEnvar is a Run* option that specifies an environment variable to set. +func WithEnvar(key, value string) Option { + return func(o *options) { + o.envars[key] = value + } } -func RunWithEncryption(t *testing.T, ftlConfigPath string, actions ...Action) { - uri := "fake-kms://CKbvh_ILElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEE6tD2yE5AWYOirhmkY-r3sYARABGKbvh_ILIAE" - t.Setenv("FTL_KMS_URI", uri) +// WithJava is a Run* option that ensures the Java runtime is built. +func WithJava() Option { + return func(o *options) { + o.requireJava = true + } +} - run(t, ftlConfigPath, true, false, actions...) +// WithoutController is a Run* option that disables starting the controller. +func WithoutController() Option { + return func(o *options) { + o.startController = false + } } -func run(t *testing.T, ftlConfigPath string, startController bool, requireJava bool, actions ...Action) { +type options struct { + languages []string + ftlConfigPath string + startController bool + requireJava bool + envars map[string]string +} + +// Run an integration test. +func Run(t *testing.T, actionsOrOptions ...ActionOrOption) { + run(t, actionsOrOptions...) +} + +func run(t *testing.T, actionsOrOptions ...ActionOrOption) { + opts := options{ + startController: true, + languages: []string{"go"}, + envars: map[string]string{}, + } + actions := []Action{} + for _, opt := range actionsOrOptions { + switch o := opt.(type) { + case Action: + actions = append(actions, o) + + case func(t testing.TB, ic TestContext): + actions = append(actions, Action(o)) + + case Option: + o(&opts) + + case func(*options): + o(&opts) + + default: + panic(fmt.Sprintf("expected Option or Action, not %T", opt)) + } + } + + for key, value := range opts.envars { + t.Setenv(key, value) + } + tmpDir := t.TempDir() cwd, err := os.Getwd() @@ -92,12 +143,13 @@ func run(t *testing.T, ftlConfigPath string, startController bool, requireJava b rootDir, ok := internal.GitRoot("").Get() assert.True(t, ok) - if ftlConfigPath != "" { - ftlConfigPath = filepath.Join(cwd, "testdata", "go", ftlConfigPath) + if opts.ftlConfigPath != "" { + // TODO: We shouldn't be copying the shared config from the "go" testdata... + opts.ftlConfigPath = filepath.Join(cwd, "testdata", "go", opts.ftlConfigPath) projectPath := filepath.Join(tmpDir, "ftl-project.toml") // Copy the specified FTL config to the temporary directory. - err = copy.Copy(ftlConfigPath, projectPath) + err = copy.Copy(opts.ftlConfigPath, projectPath) if err == nil { t.Setenv("FTL_CONFIG", projectPath) } else { @@ -106,8 +158,8 @@ func run(t *testing.T, ftlConfigPath string, startController bool, requireJava b // can't be loaded until the module is copied over, and the config itself // is used by FTL during startup. // Some tests still rely on this behavior, so we can't remove it entirely. - t.Logf("Failed to copy %s to %s: %s", ftlConfigPath, projectPath, err) - t.Setenv("FTL_CONFIG", ftlConfigPath) + t.Logf("Failed to copy %s to %s: %s", opts.ftlConfigPath, projectPath, err) + t.Setenv("FTL_CONFIG", opts.ftlConfigPath) } } else { @@ -124,49 +176,53 @@ func run(t *testing.T, ftlConfigPath string, startController bool, requireJava b Infof("Building ftl") err = ftlexec.Command(ctx, log.Debug, rootDir, "just", "build", "ftl").RunBuffered(ctx) assert.NoError(t, err) - if requireJava { + if opts.requireJava { err = ftlexec.Command(ctx, log.Debug, rootDir, "just", "build-java").RunBuffered(ctx) assert.NoError(t, err) } }) - verbs := rpc.Dial(ftlv1connect.NewVerbServiceClient, "http://localhost:8892", log.Debug) - - var controller ftlv1connect.ControllerServiceClient - var console pbconsoleconnect.ConsoleServiceClient - if startController { - controller = rpc.Dial(ftlv1connect.NewControllerServiceClient, "http://localhost:8892", log.Debug) - console = rpc.Dial(pbconsoleconnect.NewConsoleServiceClient, "http://localhost:8892", log.Debug) - - Infof("Starting ftl cluster") - ctx = startProcess(ctx, t, filepath.Join(binDir, "ftl"), "serve", "--recreate") - } - - ic := TestContext{ - Context: ctx, - RootDir: rootDir, - testData: filepath.Join(cwd, "testdata", "go"), - workDir: tmpDir, - binDir: binDir, - Verbs: verbs, - } - - if startController { - ic.Controller = controller - ic.Console = console - - Infof("Waiting for controller to be ready") - ic.AssertWithRetry(t, func(t testing.TB, ic TestContext) { - _, err := ic.Controller.Status(ic, connect.NewRequest(&ftlv1.StatusRequest{})) - assert.NoError(t, err) + for _, language := range opts.languages { + t.Run(language, func(t *testing.T) { + verbs := rpc.Dial(ftlv1connect.NewVerbServiceClient, "http://localhost:8892", log.Debug) + + var controller ftlv1connect.ControllerServiceClient + var console pbconsoleconnect.ConsoleServiceClient + if opts.startController { + controller = rpc.Dial(ftlv1connect.NewControllerServiceClient, "http://localhost:8892", log.Debug) + console = rpc.Dial(pbconsoleconnect.NewConsoleServiceClient, "http://localhost:8892", log.Debug) + + Infof("Starting ftl cluster") + ctx = startProcess(ctx, t, filepath.Join(binDir, "ftl"), "serve", "--recreate") + } + + ic := TestContext{ + Context: ctx, + RootDir: rootDir, + testData: filepath.Join(cwd, "testdata", language), + workDir: tmpDir, + binDir: binDir, + Verbs: verbs, + } + + if opts.startController { + ic.Controller = controller + ic.Console = console + + Infof("Waiting for controller to be ready") + ic.AssertWithRetry(t, func(t testing.TB, ic TestContext) { + _, err := ic.Controller.Status(ic, connect.NewRequest(&ftlv1.StatusRequest{})) + assert.NoError(t, err) + }) + } + + Infof("Starting test") + + for _, action := range actions { + ic.AssertWithRetry(t, action) + } }) } - - Infof("Starting test") - - for _, action := range actions { - ic.AssertWithRetry(t, action) - } } type TestContext struct { @@ -249,7 +305,7 @@ func (l *logWriter) Write(p []byte) (n int, err error) { } } -// startProcess runs a binary in the background. +// startProcess runs a binary in the background and terminates it when the test completes. func startProcess(ctx context.Context, t testing.TB, args ...string) context.Context { t.Helper() ctx, cancel := context.WithCancel(ctx) diff --git a/internal/encryption/integration_test.go b/internal/encryption/integration_test.go index 4b0c35d50e..d56462e10c 100644 --- a/internal/encryption/integration_test.go +++ b/internal/encryption/integration_test.go @@ -24,8 +24,13 @@ import ( awsv1kms "github.com/aws/aws-sdk-go/service/kms" ) +func WithEncryption() in.Option { + return in.WithEnvar("FTL_KMS_URI", "fake-kms://CKbvh_ILElQKSAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5EhIaEE6tD2yE5AWYOirhmkY-r3sYARABGKbvh_ILIAE") +} + func TestEncryptionForLogs(t *testing.T) { - in.RunWithEncryption(t, "", + in.Run(t, + WithEncryption(), in.CopyModule("encryption"), in.Deploy("encryption"), in.Call[map[string]interface{}, any]("encryption", "echo", map[string]interface{}{"name": "Alice"}, nil), @@ -61,7 +66,8 @@ func TestEncryptionForLogs(t *testing.T) { } func TestEncryptionForPubSub(t *testing.T) { - in.RunWithEncryption(t, "", + in.Run(t, + WithEncryption(), in.CopyModule("encryption"), in.Deploy("encryption"), in.Call[map[string]interface{}, any]("encryption", "publish", map[string]interface{}{"name": "AliceInWonderland"}, nil), @@ -81,7 +87,8 @@ func TestEncryptionForPubSub(t *testing.T) { } func TestEncryptionForFSM(t *testing.T) { - in.RunWithEncryption(t, "", + in.Run(t, + WithEncryption(), in.CopyModule("encryption"), in.Deploy("encryption"), in.Call[map[string]interface{}, any]("encryption", "beginFsm", map[string]interface{}{"name": "Rosebud"}, nil), diff --git a/java-runtime/java_integration_test.go b/java-runtime/java_integration_test.go index d64f14854a..0680b4989f 100644 --- a/java-runtime/java_integration_test.go +++ b/java-runtime/java_integration_test.go @@ -14,7 +14,8 @@ import ( ) func TestJavaToGoCall(t *testing.T) { - in.RunWithJava(t, "", + in.Run(t, + in.WithJava(), in.CopyModule("gomodule"), in.CopyDir("javamodule", "javamodule"), in.Deploy("gomodule"), From acb7f5d4c2e133773051ce3afb570a5cdcd5acd2 Mon Sep 17 00:00:00 2001 From: Safeer Jiwan Date: Wed, 14 Aug 2024 11:34:59 -0700 Subject: [PATCH 35/35] revert: "feat: register db.sql metrics (#2305)" (#2365) This reverts commit 1028e65. --- .../controller/sql/databasetesting/devel.go | 14 ++------- cmd/ftl-controller/main.go | 7 ++--- cmd/ftl/cmd_box_run.go | 9 ++---- cmd/ftl/cmd_serve.go | 11 ++----- examples/go/echo/go.mod | 1 - examples/go/echo/go.sum | 4 --- .../testdata/go/runtimereflection/go.mod | 1 - .../testdata/go/runtimereflection/go.sum | 4 --- go.mod | 4 +-- go.sum | 2 -- internal/modulecontext/database.go | 11 ++----- internal/observability/client_test.go | 2 +- internal/reflect/reflect.go | 31 +------------------ internal/reflect/reflect_test.go | 21 ------------- 14 files changed, 14 insertions(+), 108 deletions(-) diff --git a/backend/controller/sql/databasetesting/devel.go b/backend/controller/sql/databasetesting/devel.go index e2a3a06c72..a52f3fb4c2 100644 --- a/backend/controller/sql/databasetesting/devel.go +++ b/backend/controller/sql/databasetesting/devel.go @@ -8,9 +8,7 @@ import ( "strings" "time" - "github.com/XSAM/otelsql" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/internal/log" @@ -31,13 +29,9 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*stdsql.DB, var conn *stdsql.DB for range 10 { - conn, err = otelsql.Open("pgx", noDBDSN.String()) + conn, err = stdsql.Open("pgx", noDBDSN.String()) if err == nil { defer conn.Close() - err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) - if err != nil { - panic(err) - } break } logger.Debugf("Waiting for database to be ready: %v", err) @@ -78,14 +72,10 @@ func CreateForDevel(ctx context.Context, dsn string, recreate bool) (*stdsql.DB, return nil, err } - realConn, err := otelsql.Open("pgx", dsn) + realConn, err := stdsql.Open("pgx", dsn) if err != nil { return nil, fmt.Errorf("failed to open database: %w", err) } - err = otelsql.RegisterDBStatsMetrics(realConn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) - if err != nil { - return nil, fmt.Errorf("failed to register db metrics: %w", err) - } // Reset transient state in the database to a clean state for development purposes. // This includes things like resetting the state of async calls, leases, // controller/runner registration, etc. but not anything more. diff --git a/cmd/ftl-controller/main.go b/cmd/ftl-controller/main.go index 83c2e88a46..42b0a54d01 100644 --- a/cmd/ftl-controller/main.go +++ b/cmd/ftl-controller/main.go @@ -2,17 +2,16 @@ package main import ( "context" + "database/sql" "fmt" "os" "strconv" "time" - "github.com/XSAM/otelsql" "github.com/alecthomas/kong" "github.com/alecthomas/types/optional" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "github.com/TBD54566975/ftl" "github.com/TBD54566975/ftl/backend/controller" @@ -54,9 +53,7 @@ func main() { kctx.FatalIfErrorf(err, "failed to initialize observability") // The FTL controller currently only supports DB as a configuration provider/resolver. - conn, err := otelsql.Open("pgx", cli.ControllerConfig.DSN) - kctx.FatalIfErrorf(err) - err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + conn, err := sql.Open("pgx", cli.ControllerConfig.DSN) kctx.FatalIfErrorf(err) dal, err := dal.New(ctx, conn, optional.Some[string](*cli.ControllerConfig.KMSURI)) kctx.FatalIfErrorf(err) diff --git a/cmd/ftl/cmd_box_run.go b/cmd/ftl/cmd_box_run.go index 1fe6717591..971df8a915 100644 --- a/cmd/ftl/cmd_box_run.go +++ b/cmd/ftl/cmd_box_run.go @@ -2,14 +2,13 @@ package main import ( "context" + "database/sql" "fmt" "net/url" "time" - "github.com/XSAM/otelsql" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver "github.com/jpillora/backoff" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl/backend/controller" @@ -59,14 +58,10 @@ func (b *boxRunCmd) Run(ctx context.Context, projConfig projectconfig.Config) er } // Bring up the DB connection and DAL. - conn, err := otelsql.Open("pgx", config.DSN) + conn, err := sql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } - err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) - if err != nil { - return fmt.Errorf("failed to register DB metrics: %w", err) - } wg := errgroup.Group{} wg.Go(func() error { diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 985181b913..62bfd843c6 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -2,6 +2,7 @@ package main import ( "context" + "database/sql" "errors" "fmt" "net" @@ -14,10 +15,8 @@ import ( "time" "connectrpc.com/connect" - "github.com/XSAM/otelsql" "github.com/alecthomas/types/optional" _ "github.com/jackc/pgx/v5/stdlib" // pgx driver - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl" @@ -148,15 +147,11 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini } controllerCtx = cf.ContextWithSecrets(controllerCtx, sm) - // Bring up the DB connection for the controller. - conn, err := otelsql.Open("pgx", config.DSN) + // Bring up the DB connection and DAL. + conn, err := sql.Open("pgx", config.DSN) if err != nil { return fmt.Errorf("failed to bring up DB connection: %w", err) } - err = otelsql.RegisterDBStatsMetrics(conn, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) - if err != nil { - return fmt.Errorf("failed to register DB metrics: %w", err) - } wg.Go(func() error { if err := controller.Start(controllerCtx, config, runnerScaling, conn); err != nil { diff --git a/examples/go/echo/go.mod b/examples/go/echo/go.mod index 7769185838..272b973492 100644 --- a/examples/go/echo/go.mod +++ b/examples/go/echo/go.mod @@ -10,7 +10,6 @@ require ( connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect connectrpc.com/otelconnect v0.7.1 // indirect - github.com/XSAM/otelsql v0.32.0 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect diff --git a/examples/go/echo/go.sum b/examples/go/echo/go.sum index 9569a27c55..9fbb9ebc36 100644 --- a/examples/go/echo/go.sum +++ b/examples/go/echo/go.sum @@ -6,8 +6,6 @@ connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= -github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= -github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= @@ -134,8 +132,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod index ce3ab84d32..f190123044 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.mod @@ -11,7 +11,6 @@ require ( connectrpc.com/connect v1.16.2 // indirect connectrpc.com/grpcreflect v1.2.0 // indirect connectrpc.com/otelconnect v0.7.1 // indirect - github.com/XSAM/otelsql v0.32.0 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alecthomas/concurrency v0.0.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect diff --git a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum index 9569a27c55..9fbb9ebc36 100644 --- a/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum +++ b/go-runtime/ftl/reflection/testdata/go/runtimereflection/go.sum @@ -6,8 +6,6 @@ connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= -github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= -github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= @@ -134,8 +132,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= diff --git a/go.mod b/go.mod index 46285e945b..229522885f 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/BurntSushi/toml v1.4.0 github.com/TBD54566975/golang-tools v0.2.1 github.com/TBD54566975/scaffolder v1.0.0 - github.com/XSAM/otelsql v0.32.0 github.com/alecthomas/assert/v2 v2.10.0 github.com/alecthomas/atomic v0.1.0-alpha2 github.com/alecthomas/chroma/v2 v2.14.0 @@ -69,7 +68,6 @@ require ( golang.org/x/sync v0.8.0 golang.org/x/term v0.23.0 google.golang.org/protobuf v1.34.2 - gotest.tools/v3 v3.5.1 modernc.org/sqlite v1.32.0 ) @@ -89,7 +87,6 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/iancoleman/strcase v0.3.0 // indirect @@ -113,6 +110,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/tools v0.23.0 // indirect + gotest.tools/v3 v3.5.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect ) diff --git a/go.sum b/go.sum index d6974f3379..93f56bfac0 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,6 @@ github.com/TBD54566975/golang-tools v0.2.1 h1:jzP27dzvJRb43Z9xTbRCPOT/rZD43FZkqV github.com/TBD54566975/golang-tools v0.2.1/go.mod h1:rEEXIq0/pFgZqi/MTOq4DBmVpLHLgI9WocJWXYhu050= github.com/TBD54566975/scaffolder v1.0.0 h1:QUFSy2wVzumLDg7IHcKC6AP+IYyqWe9Wxiu72nZn5qU= github.com/TBD54566975/scaffolder v1.0.0/go.mod h1:auVpczIbOAdIhYDVSruIw41DanxOKB9bSvjf6MEl7Fs= -github.com/XSAM/otelsql v0.32.0 h1:vDRE4nole0iOOlTaC/Bn6ti7VowzgxK39n3Ll1Kt7i0= -github.com/XSAM/otelsql v0.32.0/go.mod h1:Ary0hlyVBbaSwo8atZB8Aoothg9s/LBJj/N/p5qDmLM= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= diff --git a/internal/modulecontext/database.go b/internal/modulecontext/database.go index 7416a80df6..fef41e6f54 100644 --- a/internal/modulecontext/database.go +++ b/internal/modulecontext/database.go @@ -5,9 +5,6 @@ import ( "fmt" "strconv" - "github.com/XSAM/otelsql" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" - ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" ) @@ -22,13 +19,9 @@ type Database struct { // NewDatabase creates a Database that can be added to ModuleContext func NewDatabase(dbType DBType, dsn string) (Database, error) { - db, err := otelsql.Open("pgx", dsn) - if err != nil { - return Database{}, fmt.Errorf("failed to open database: %w", err) - } - err = otelsql.RegisterDBStatsMetrics(db, otelsql.WithAttributes(semconv.DBSystemPostgreSQL)) + db, err := sql.Open("pgx", dsn) if err != nil { - return Database{}, fmt.Errorf("failed to register db metrics: %w", err) + return Database{}, fmt.Errorf("failed to bring up DB connection: %w", err) } return Database{ DSN: dsn, diff --git a/internal/observability/client_test.go b/internal/observability/client_test.go index b1582ba137..1cb3537ac4 100644 --- a/internal/observability/client_test.go +++ b/internal/observability/client_test.go @@ -10,5 +10,5 @@ import ( func TestSchemaMismatch(t *testing.T) { dflt := resource.Default() - assert.Equal(t, dflt.SchemaURL(), schemaURL, `in every file that imports go.opentelemetry.io/otel/semconv, change the import to: semconv "go.opentelemetry.io/otel/semconv/v%s"`, path.Base(dflt.SchemaURL())) + assert.Equal(t, dflt.SchemaURL(), schemaURL, `change import in client.go to: semconv "go.opentelemetry.io/otel/semconv/v%s"`, path.Base(dflt.SchemaURL())) } diff --git a/internal/reflect/reflect.go b/internal/reflect/reflect.go index c0a19776eb..079c4edb93 100644 --- a/internal/reflect/reflect.go +++ b/internal/reflect/reflect.go @@ -13,7 +13,6 @@ package reflect import ( - "container/list" "fmt" "reflect" "strings" @@ -132,11 +131,6 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { return src } - // Special case list.List to handle its internal structure - if reflect.TypeOf(src) == reflect.TypeFor[*list.List]() { - return copyList(src.(*list.List), ptrs, copyConf) - } - // Look up the corresponding copy function. switch v.Kind() { case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, @@ -145,11 +139,7 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { reflect.Complex64, reflect.Complex128, reflect.Func: dst = copyPremitive(src, ptrs, copyConf) case reflect.String: - if v.Type() == reflect.TypeFor[string]() { - dst = strings.Clone(src.(string)) - } else { - dst = copyStringAlias(src, ptrs, copyConf) - } + dst = strings.Clone(src.(string)) case reflect.Slice: dst = copySlice(src, ptrs, copyConf) case reflect.Array: @@ -170,18 +160,6 @@ func copyAny(src any, ptrs map[uintptr]any, copyConf *copyConfig) (dst any) { return } -func copyList(src *list.List, ptrs map[uintptr]any, copyConf *copyConfig) *list.List { - if src == nil { - return nil - } - dst := list.New() - for e := src.Front(); e != nil; e = e.Next() { - copiedValue := copyAny(e.Value, ptrs, copyConf) - dst.PushBack(copiedValue) - } - return dst -} - func copyPremitive(src any, ptr map[uintptr]any, copyConf *copyConfig) (dst any) { kind := reflect.ValueOf(src).Kind() switch kind { @@ -192,13 +170,6 @@ func copyPremitive(src any, ptr map[uintptr]any, copyConf *copyConfig) (dst any) return } -func copyStringAlias(src any, ptr map[uintptr]any, copyConf *copyConfig) any { - v := reflect.ValueOf(src) - dc := reflect.New(v.Type()).Elem() - dc.Set(v) - return dc.Interface() -} - func copySlice(x any, ptrs map[uintptr]any, copyConf *copyConfig) any { v := reflect.ValueOf(x) kind := v.Kind() diff --git a/internal/reflect/reflect_test.go b/internal/reflect/reflect_test.go index e525943aaf..a6f138e042 100644 --- a/internal/reflect/reflect_test.go +++ b/internal/reflect/reflect_test.go @@ -1,30 +1,9 @@ package reflect import ( - "container/list" "testing" - - "gotest.tools/v3/assert" ) -type mystring string -type structWithMystring struct { - str mystring -} - -func TestAliasedString(t *testing.T) { - output := DeepCopy(structWithMystring{"asdf"}) - assert.Equal(t, output, structWithMystring{"asdf"}) -} - -func TestListElements(t *testing.T) { - l := list.New() - l.PushBack("one") - output := DeepCopy(l) - assert.Equal(t, output.Front().Value, l.Front().Value) - assert.Equal(t, output.Len(), l.Len()) -} - type structOfPointers struct { intPtr *int floatPtr *float64