From 836fc77ddce700a2d6e7aa399461d2059abd3764 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Fri, 2 May 2025 10:27:41 +0300 Subject: [PATCH] [#6689] updated to automatically routes raw write SQL statements to the nonconcurrent db pool --- CHANGELOG.md | 3 + apis/realtime.go | 2 +- apis/record_crud.go | 6 +- apis/record_helpers.go | 4 +- core/app.go | 72 +- core/base.go | 80 +- core/base_test.go | 169 +- core/collection_model_test.go | 2 +- core/collection_query_test.go | 4 +- core/collection_record_table_sync.go | 5 +- core/collection_validate.go | 4 +- core/db.go | 10 +- core/db_builder.go | 187 + core/db_table.go | 26 +- core/db_table_test.go | 8 +- core/db_test.go | 8 +- core/external_auth_query_test.go | 2 +- core/field_file.go | 4 +- core/field_relation.go | 2 +- core/field_text.go | 2 +- core/log_printer_test.go | 8 +- core/record_model_test.go | 4 +- core/record_query.go | 2 +- core/record_query_expand.go | 2 +- forms/record_upsert.go | 2 +- .../jsvm/internal/types/generated/types.d.ts | 7895 +++++++++-------- tools/filesystem/filesystem.go | 5 +- 27 files changed, 4601 insertions(+), 3917 deletions(-) create mode 100644 core/db_builder.go diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ca9b50..69ffb18a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ - Write the default response body of `*Request` hooks that are wrapped in a transaction after the related transaction completes to allow propagating errors ([#6462](https://github.com/pocketbase/pocketbase/discussions/6462#discussioncomment-12207818)). +- Updated `app.DB()` to automatically routes raw write SQL statements to the nonconcurrent db pool ([#6689](https://github.com/pocketbase/pocketbase/discussions/6689)). + _For the rare cases when it is needed users still have the option to explicitly target the specific pool they want using `app.ConcurrentDB()`/`app.NonconcurrentDB()`._ + ## v0.27.2 diff --git a/apis/realtime.go b/apis/realtime.go index a70093b2..0b68317f 100644 --- a/apis/realtime.go +++ b/apis/realtime.go @@ -758,7 +758,7 @@ func realtimeCanAccessRecord( var exists int - q := app.DB().Select("(1)"). + q := app.ConcurrentDB().Select("(1)"). From(record.Collection().Name). AndWhere(dbx.HashExp{record.Collection().Name + ".id": record.Id}) diff --git a/apis/record_crud.go b/apis/record_crud.go index de7cd8d1..ff487583 100644 --- a/apis/record_crud.go +++ b/apis/record_crud.go @@ -300,7 +300,7 @@ func recordCreate(responseWriteAfterTx bool, optFinalizer func(data any) error) // check non-empty create rule if *dummyCollection.CreateRule != "" { - ruleQuery := e.App.DB().Select("(1)").PreFragment(withFrom).From(dummyCollection.Name).AndBind(dummyParams) + ruleQuery := e.App.ConcurrentDB().Select("(1)").PreFragment(withFrom).From(dummyCollection.Name).AndBind(dummyParams) resolver := core.NewRecordFieldResolver(e.App, &dummyCollection, requestInfo, true) @@ -320,7 +320,7 @@ func recordCreate(responseWriteAfterTx bool, optFinalizer func(data any) error) } // check for manage rule access - manageRuleQuery := e.App.DB().Select("(1)").PreFragment(withFrom).From(dummyCollection.Name).AndBind(dummyParams) + manageRuleQuery := e.App.ConcurrentDB().Select("(1)").PreFragment(withFrom).From(dummyCollection.Name).AndBind(dummyParams) if !form.HasManageAccess() && hasAuthManageAccess(e.App, requestInfo, &dummyCollection, manageRuleQuery) { form.GrantManagerAccess() @@ -452,7 +452,7 @@ func recordUpdate(responseWriteAfterTx bool, optFinalizer func(data any) error) } form.Load(data) - manageRuleQuery := e.App.DB().Select("(1)").From(collection.Name).AndWhere(dbx.HashExp{ + manageRuleQuery := e.App.ConcurrentDB().Select("(1)").From(collection.Name).AndWhere(dbx.HashExp{ collection.Name + ".id": record.Id, }) if !form.HasManageAccess() && diff --git a/apis/record_helpers.go b/apis/record_helpers.go index 3ba5e341..b15d241f 100644 --- a/apis/record_helpers.go +++ b/apis/record_helpers.go @@ -457,8 +457,8 @@ func autoResolveRecordsFlags(app core.App, records []*core.Record, requestInfo * managedIds := []string{} query := app.RecordQuery(collection). - Select(app.DB().QuoteSimpleColumnName(collection.Name) + ".id"). - AndWhere(dbx.In(app.DB().QuoteSimpleColumnName(collection.Name)+".id", recordIds...)) + Select(app.ConcurrentDB().QuoteSimpleColumnName(collection.Name) + ".id"). + AndWhere(dbx.In(app.ConcurrentDB().QuoteSimpleColumnName(collection.Name)+".id", recordIds...)) resolver := core.NewRecordFieldResolver(app, collection, requestInfo, true) expr, err := search.FilterData(*collection.ManageRule).BuildExpr(resolver) diff --git a/core/app.go b/core/app.go index 4c6247a0..df2b354a 100644 --- a/core/app.go +++ b/core/app.go @@ -146,46 +146,82 @@ type App interface { // DB methods // --------------------------------------------------------------- - // DB returns the default app data db instance (pb_data/data.db). + // DB returns the default app data.db builder instance. + // + // To minimize SQLITE_BUSY errors, it automatically routes the + // SELECT queries to the underlying concurrent db pool and everything else + // to the nonconcurrent one. + // + // For more finer control over the used connections pools you can + // call directly ConcurrentDB() or NonconcurrentDB(). DB() dbx.Builder - // NonconcurrentDB returns the nonconcurrent app data db instance (pb_data/data.db). + // ConcurrentDB returns the concurrent app data.db builder instance. + // + // This method is used mainly internally for executing db read + // operations in a concurrent/non-blocking manner. + // + // Most users should use simply DB() as it will automatically + // route the query execution to ConcurrentDB() or NonconcurrentDB(). + // + // In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + ConcurrentDB() dbx.Builder + + // NonconcurrentDB returns the nonconcurrent app data.db builder instance. // // The returned db instance is limited only to a single open connection, - // meaning that it can process only 1 db operation at a time (other operations will be queued up). + // meaning that it can process only 1 db operation at a time (other queries queue up). // // This method is used mainly internally and in the tests to execute write // (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. // - // For the majority of cases you would want to use the regular DB() method - // since it allows concurrent db read operations. + // Most users should use simply DB() as it will automatically + // route the query execution to ConcurrentDB() or NonconcurrentDB(). // // In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. NonconcurrentDB() dbx.Builder - // AuxDB returns the default app auxiliary db instance (pb_data/auxiliary.db). + // AuxDB returns the app auxiliary.db builder instance. + // + // To minimize SQLITE_BUSY errors, it automatically routes the + // SELECT queries to the underlying concurrent db pool and everything else + // to the nonconcurrent one. + // + // For more finer control over the used connections pools you can + // call directly AuxConcurrentDB() or AuxNonconcurrentDB(). AuxDB() dbx.Builder - // AuxNonconcurrentDB returns the nonconcurrent app auxiliary db instance (pb_data/auxiliary.db).. + // AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. + // + // This method is used mainly internally for executing db read + // operations in a concurrent/non-blocking manner. + // + // Most users should use simply AuxDB() as it will automatically + // route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + // + // In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + AuxConcurrentDB() dbx.Builder + + // AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. // // The returned db instance is limited only to a single open connection, - // meaning that it can process only 1 db operation at a time (other operations will be queued up). + // meaning that it can process only 1 db operation at a time (other queries queue up). // // This method is used mainly internally and in the tests to execute write // (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. // - // For the majority of cases you would want to use the regular DB() method - // since it allows concurrent db read operations. + // Most users should use simply AuxDB() as it will automatically + // route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). // - // In a transaction the AuxNonconcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + // In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. AuxNonconcurrentDB() dbx.Builder // HasTable checks if a table (or view) with the provided name exists (case insensitive). - // in the current app.DB() instance. + // in the data.db. HasTable(tableName string) bool // AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) - // in the current app.AuxDB() instance. + // in the auxiliary.db. AuxHasTable(tableName string) bool // TableColumns returns all column names of a single table by its name. @@ -231,21 +267,19 @@ type App interface { // FindRecordByViewFile returns the original Record of the provided view collection file. FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) - // Vacuum executes VACUUM on the current app.DB() instance - // in order to reclaim unused data db disk space. + // Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. Vacuum() error - // AuxVacuum executes VACUUM on the current app.AuxDB() instance - // in order to reclaim unused auxiliary db disk space. + // AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. AuxVacuum() error // --------------------------------------------------------------- - // ModelQuery creates a new preconfigured select app.DB() query with preset + // ModelQuery creates a new preconfigured select data.db query with preset // SELECT, FROM and other common fields based on the provided model. ModelQuery(model Model) *dbx.SelectQuery - // AuxModelQuery creates a new preconfigured select app.AuxDB() query with preset + // AuxModelQuery creates a new preconfigured select auxiliary.db query with preset // SELECT, FROM and other common fields based on the provided model. AuxModelQuery(model Model) *dbx.SelectQuery diff --git a/core/base.go b/core/base.go index 10acf9ce..f2865a61 100644 --- a/core/base.go +++ b/core/base.go @@ -476,44 +476,100 @@ func (app *BaseApp) ResetBootstrapState() error { return nil } -// DB returns the default app data db instance (pb_data/data.db). +// DB returns the default app data.db builder instance. +// +// To minimize SQLITE_BUSY errors, it automatically routes the +// SELECT queries to the underlying concurrent db pool and everything +// else to the nonconcurrent one. +// +// For more finer control over the used connections pools you can +// call directly ConcurrentDB() or NonconcurrentDB(). func (app *BaseApp) DB() dbx.Builder { + // transactional or both are nil + if app.concurrentDB == app.nonconcurrentDB { + return app.concurrentDB + } + + return &dualDBBuilder{ + concurrentDB: app.concurrentDB, + nonconcurrentDB: app.nonconcurrentDB, + } +} + +// ConcurrentDB returns the concurrent app data.db builder instance. +// +// This method is used mainly internally for executing db read +// operations in a concurrent/non-blocking manner. +// +// Most users should use simply DB() as it will automatically +// route the query execution to ConcurrentDB() or NonconcurrentDB(). +// +// In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. +func (app *BaseApp) ConcurrentDB() dbx.Builder { return app.concurrentDB } -// NonconcurrentDB returns the nonconcurrent app data db instance (pb_data/data.db). +// NonconcurrentDB returns the nonconcurrent app data.db builder instance. // // The returned db instance is limited only to a single open connection, -// meaning that it can process only 1 db operation at a time (other operations will be queued up). +// meaning that it can process only 1 db operation at a time (other queries queue up). // // This method is used mainly internally and in the tests to execute write // (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. // -// For the majority of cases you would want to use the regular DB() method -// since it allows concurrent db read operations. +// Most users should use simply DB() as it will automatically +// route the query execution to ConcurrentDB() or NonconcurrentDB(). // // In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. func (app *BaseApp) NonconcurrentDB() dbx.Builder { return app.nonconcurrentDB } -// AuxDB returns the default app auxiliary db instance (pb_data/auxiliary.db). +// AuxDB returns the app auxiliary.db builder instance. +// +// To minimize SQLITE_BUSY errors, it automatically routes the +// SELECT queries to the underlying concurrent db pool and everything +// else to the nonconcurrent one. +// +// For more finer control over the used connections pools you can +// call directly AuxConcurrentDB() or AuxNonconcurrentDB(). func (app *BaseApp) AuxDB() dbx.Builder { + // transactional or both are nil + if app.auxConcurrentDB == app.auxNonconcurrentDB { + return app.auxConcurrentDB + } + + return &dualDBBuilder{ + concurrentDB: app.auxConcurrentDB, + nonconcurrentDB: app.auxNonconcurrentDB, + } +} + +// AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. +// +// This method is used mainly internally for executing db read +// operations in a concurrent/non-blocking manner. +// +// Most users should use simply AuxDB() as it will automatically +// route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). +// +// In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. +func (app *BaseApp) AuxConcurrentDB() dbx.Builder { return app.auxConcurrentDB } -// AuxNonconcurrentDB returns the nonconcurrent app auxiliary db instance (pb_data/auxiliary.db). +// AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. // // The returned db instance is limited only to a single open connection, -// meaning that it can process only 1 db operation at a time (other operations will be queued up). +// meaning that it can process only 1 db operation at a time (other queries queue up). // // This method is used mainly internally and in the tests to execute write // (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. // -// For the majority of cases you would want to use the regular DB() method -// since it allows concurrent db read operations. +// Most users should use simply AuxDB() as it will automatically +// route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). // -// In a transaction the AuxNonconcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. +// In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. func (app *BaseApp) AuxNonconcurrentDB() dbx.Builder { return app.auxNonconcurrentDB } @@ -1309,7 +1365,7 @@ func (app *BaseApp) registerBaseHooks() { app.Logger().Warn("Failed to run periodic PRAGMA wal_checkpoint for the auxiliary DB", slog.String("error", execErr.Error())) } - _, execErr = app.DB().NewQuery("PRAGMA optimize").Execute() + _, execErr = app.ConcurrentDB().NewQuery("PRAGMA optimize").Execute() if execErr != nil { app.Logger().Warn("Failed to run periodic PRAGMA optimize", slog.String("error", execErr.Error())) } diff --git a/core/base_test.go b/core/base_test.go index 794dd2e9..b9b43531 100644 --- a/core/base_test.go +++ b/core/base_test.go @@ -5,6 +5,7 @@ import ( "database/sql" "log/slog" "os" + "slices" "testing" "time" @@ -99,9 +100,11 @@ func TestBaseAppBootstrap(t *testing.T) { } nilChecksBeforeReset := []nilCheck{ - {"[before] concurrentDB", app.DB(), false}, + {"[before] db", app.DB(), false}, + {"[before] concurrentDB", app.ConcurrentDB(), false}, {"[before] nonconcurrentDB", app.NonconcurrentDB(), false}, - {"[before] auxConcurrentDB", app.AuxDB(), false}, + {"[before] auxDB", app.AuxDB(), false}, + {"[before] auxConcurrentDB", app.AuxConcurrentDB(), false}, {"[before] auxNonconcurrentDB", app.AuxNonconcurrentDB(), false}, {"[before] settings", app.Settings(), false}, {"[before] logger", app.Logger(), false}, @@ -116,9 +119,11 @@ func TestBaseAppBootstrap(t *testing.T) { } nilChecksAfterReset := []nilCheck{ - {"[after] concurrentDB", app.DB(), true}, + {"[after] db", app.DB(), true}, + {"[after] concurrentDB", app.ConcurrentDB(), true}, {"[after] nonconcurrentDB", app.NonconcurrentDB(), true}, - {"[after] auxConcurrentDB", app.AuxDB(), true}, + {"[after] auxDB", app.AuxDB(), true}, + {"[after] auxConcurrentDB", app.AuxConcurrentDB(), true}, {"[after] auxNonconcurrentDB", app.AuxNonconcurrentDB(), true}, {"[after] settings", app.Settings(), false}, {"[after] logger", app.Logger(), false}, @@ -371,8 +376,8 @@ func TestBaseAppRefreshSettingsLoggerMinLevelEnabled(t *testing.T) { } // silence query logs - app.DB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} + app.ConcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} + app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} @@ -395,3 +400,155 @@ func TestBaseAppRefreshSettingsLoggerMinLevelEnabled(t *testing.T) { }) } } + +func TestBaseAppDBDualBuilder(t *testing.T) { + t.Parallel() + + app, _ := tests.NewTestApp() + defer app.Cleanup() + + concurrentQueries := []string{} + nonconcurrentQueries := []string{} + app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + concurrentQueries = append(concurrentQueries, sql) + } + app.ConcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + concurrentQueries = append(concurrentQueries, sql) + } + app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + nonconcurrentQueries = append(nonconcurrentQueries, sql) + } + app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + nonconcurrentQueries = append(nonconcurrentQueries, sql) + } + + type testQuery struct { + query string + isConcurrent bool + } + + regularTests := []testQuery{ + {" \n sEleCt 1", true}, + {"With abc(x) AS (select 2) SELECT x FROM abc", true}, + {"create table t1(x int)", false}, + {"insert into t1(x) values(1)", false}, + {"update t1 set x = 2", false}, + {"delete from t1", false}, + } + + txTests := []testQuery{ + {"select 3", false}, + {" \n WITH abc(x) AS (select 4) SELECT x FROM abc", false}, + {"create table t2(x int)", false}, + {"insert into t2(x) values(1)", false}, + {"update t2 set x = 2", false}, + {"delete from t2", false}, + } + + for _, item := range regularTests { + _, err := app.DB().NewQuery(item.query).Execute() + if err != nil { + t.Fatalf("Failed to execute query %q error: %v", item.query, err) + } + } + + app.RunInTransaction(func(txApp core.App) error { + for _, item := range txTests { + _, err := txApp.DB().NewQuery(item.query).Execute() + if err != nil { + t.Fatalf("Failed to execute query %q error: %v", item.query, err) + } + } + + return nil + }) + + allTests := append(regularTests, txTests...) + for _, item := range allTests { + if item.isConcurrent { + if !slices.Contains(concurrentQueries, item.query) { + t.Fatalf("Expected concurrent query\n%q\ngot\nconcurrent:%v\nnonconcurrent:%v", item.query, concurrentQueries, nonconcurrentQueries) + } + } else { + if !slices.Contains(nonconcurrentQueries, item.query) { + t.Fatalf("Expected nonconcurrent query\n%q\ngot\nconcurrent:%v\nnonconcurrent:%v", item.query, concurrentQueries, nonconcurrentQueries) + } + } + } +} + +func TestBaseAppAuxDBDualBuilder(t *testing.T) { + t.Parallel() + + app, _ := tests.NewTestApp() + defer app.Cleanup() + + concurrentQueries := []string{} + nonconcurrentQueries := []string{} + app.AuxConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + concurrentQueries = append(concurrentQueries, sql) + } + app.AuxConcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + concurrentQueries = append(concurrentQueries, sql) + } + app.AuxNonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + nonconcurrentQueries = append(nonconcurrentQueries, sql) + } + app.AuxNonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + nonconcurrentQueries = append(nonconcurrentQueries, sql) + } + + type testQuery struct { + query string + isConcurrent bool + } + + regularTests := []testQuery{ + {" \n sEleCt 1", true}, + {"With abc(x) AS (select 2) SELECT x FROM abc", true}, + {"create table t1(x int)", false}, + {"insert into t1(x) values(1)", false}, + {"update t1 set x = 2", false}, + {"delete from t1", false}, + } + + txTests := []testQuery{ + {"select 3", false}, + {" \n WITH abc(x) AS (select 4) SELECT x FROM abc", false}, + {"create table t2(x int)", false}, + {"insert into t2(x) values(1)", false}, + {"update t2 set x = 2", false}, + {"delete from t2", false}, + } + + for _, item := range regularTests { + _, err := app.AuxDB().NewQuery(item.query).Execute() + if err != nil { + t.Fatalf("Failed to execute query %q error: %v", item.query, err) + } + } + + app.AuxRunInTransaction(func(txApp core.App) error { + for _, item := range txTests { + _, err := txApp.AuxDB().NewQuery(item.query).Execute() + if err != nil { + t.Fatalf("Failed to execute query %q error: %v", item.query, err) + } + } + + return nil + }) + + allTests := append(regularTests, txTests...) + for _, item := range allTests { + if item.isConcurrent { + if !slices.Contains(concurrentQueries, item.query) { + t.Fatalf("Expected concurrent query\n%q\ngot\nconcurrent:%v\nnonconcurrent:%v", item.query, concurrentQueries, nonconcurrentQueries) + } + } else { + if !slices.Contains(nonconcurrentQueries, item.query) { + t.Fatalf("Expected nonconcurrent query\n%q\ngot\nconcurrent:%v\nnonconcurrent:%v", item.query, concurrentQueries, nonconcurrentQueries) + } + } + } +} diff --git a/core/collection_model_test.go b/core/collection_model_test.go index f76f2bb0..ba0abf88 100644 --- a/core/collection_model_test.go +++ b/core/collection_model_test.go @@ -1623,7 +1623,7 @@ func TestCollectionSaveViewWrapping(t *testing.T) { var sql string - rowErr := app.DB().NewQuery("SELECT sql FROM sqlite_master WHERE type='view' AND name={:name}"). + rowErr := app.ConcurrentDB().NewQuery("SELECT sql FROM sqlite_master WHERE type='view' AND name={:name}"). Bind(dbx.Params{"name": viewName}). Row(&sql) if rowErr != nil { diff --git a/core/collection_query_test.go b/core/collection_query_test.go index 4e39f870..2bef7cfe 100644 --- a/core/collection_query_test.go +++ b/core/collection_query_test.go @@ -153,7 +153,7 @@ func TestFindCachedCollectionByNameOrId(t *testing.T) { defer app.Cleanup() totalQueries := 0 - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { totalQueries++ } @@ -272,7 +272,7 @@ func TestFindCachedCollectionReferences(t *testing.T) { } totalQueries := 0 - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { totalQueries++ } diff --git a/core/collection_record_table_sync.go b/core/collection_record_table_sync.go index 6a42ae11..3ecf2080 100644 --- a/core/collection_record_table_sync.go +++ b/core/collection_record_table_sync.go @@ -144,7 +144,7 @@ func (app *BaseApp) SyncRecordTableSchema(newCollection *Collection, oldCollecti // run optimize per the SQLite recommendations // (https://www.sqlite.org/pragma.html#pragma_optimize) - _, optimizeErr := app.DB().NewQuery("PRAGMA optimize").Execute() + _, optimizeErr := app.ConcurrentDB().NewQuery("PRAGMA optimize").Execute() if optimizeErr != nil { app.Logger().Warn("Failed to run PRAGMA optimize after record table sync", slog.String("error", optimizeErr.Error())) } @@ -310,7 +310,8 @@ func dropCollectionIndexes(app App, collection *Collection) error { continue } - if _, err := app.DB().NewQuery(fmt.Sprintf("DROP INDEX IF EXISTS [[%s]]", parsed.IndexName)).Execute(); err != nil { + _, err := txApp.DB().NewQuery(fmt.Sprintf("DROP INDEX IF EXISTS [[%s]]", parsed.IndexName)).Execute() + if err != nil { return err } } diff --git a/core/collection_validate.go b/core/collection_validate.go index 56d23eda..a3506aba 100644 --- a/core/collection_validate.go +++ b/core/collection_validate.go @@ -87,7 +87,7 @@ func (validator *collectionValidator) run() error { validator.original.IsNew(), validation.Length(1, 100), validation.Match(DefaultIdRegex), - validation.By(validators.UniqueId(validator.app.DB(), validator.new.TableName())), + validation.By(validators.UniqueId(validator.app.ConcurrentDB(), validator.new.TableName())), ).Else( validation.By(validators.Equal(validator.original.Id)), ), @@ -558,7 +558,7 @@ func (cv *collectionValidator) checkIndexes(value any) error { // ensure that the index name is not used in another collection var usedTblName string - _ = cv.app.DB().Select("tbl_name"). + _ = cv.app.ConcurrentDB().Select("tbl_name"). From("sqlite_master"). AndWhere(dbx.HashExp{"type": "index"}). AndWhere(dbx.NewExp("LOWER([[tbl_name]])!=LOWER({:oldName})", dbx.Params{"oldName": cv.original.Name})). diff --git a/core/db.go b/core/db.go index 9c3312d2..71fa8294 100644 --- a/core/db.go +++ b/core/db.go @@ -62,16 +62,16 @@ func crc32Checksum(str string) string { return strconv.FormatInt(int64(crc32.ChecksumIEEE([]byte(str))), 10) } -// ModelQuery creates a new preconfigured select app.DB() query with preset +// ModelQuery creates a new preconfigured select data.db query with preset // SELECT, FROM and other common fields based on the provided model. func (app *BaseApp) ModelQuery(m Model) *dbx.SelectQuery { - return app.modelQuery(app.DB(), m) + return app.modelQuery(app.ConcurrentDB(), m) } -// AuxModelQuery creates a new preconfigured select app.AuxDB() query with preset +// AuxModelQuery creates a new preconfigured select auxiliary.db query with preset // SELECT, FROM and other common fields based on the provided model. func (app *BaseApp) AuxModelQuery(m Model) *dbx.SelectQuery { - return app.modelQuery(app.AuxDB(), m) + return app.modelQuery(app.AuxConcurrentDB(), m) } func (app *BaseApp) modelQuery(db dbx.Builder, m Model) *dbx.SelectQuery { @@ -484,7 +484,7 @@ func validateRecordId(app App, collectionNameOrId string) validation.RuleFunc { var exists int - rowErr := app.DB().Select("(1)"). + rowErr := app.ConcurrentDB().Select("(1)"). From(collection.Name). AndWhere(dbx.HashExp{"id": id}). Limit(1). diff --git a/core/db_builder.go b/core/db_builder.go new file mode 100644 index 00000000..021e9c91 --- /dev/null +++ b/core/db_builder.go @@ -0,0 +1,187 @@ +package core + +import ( + "strings" + "unicode" + "unicode/utf8" + + "github.com/pocketbase/dbx" +) + +var _ dbx.Builder = (*dualDBBuilder)(nil) + +// note: expects both builder to use the same driver +type dualDBBuilder struct { + concurrentDB dbx.Builder + nonconcurrentDB dbx.Builder +} + +// Select implements the [dbx.Builder.Select] interface method. +func (b *dualDBBuilder) Select(cols ...string) *dbx.SelectQuery { + return b.concurrentDB.Select(cols...) +} + +// Model implements the [dbx.Builder.Model] interface method. +func (b *dualDBBuilder) Model(data interface{}) *dbx.ModelQuery { + return b.nonconcurrentDB.Model(data) +} + +// GeneratePlaceholder implements the [dbx.Builder.GeneratePlaceholder] interface method. +func (b *dualDBBuilder) GeneratePlaceholder(i int) string { + return b.concurrentDB.GeneratePlaceholder(i) +} + +// Quote implements the [dbx.Builder.Quote] interface method. +func (b *dualDBBuilder) Quote(str string) string { + return b.concurrentDB.Quote(str) +} + +// QuoteSimpleTableName implements the [dbx.Builder.QuoteSimpleTableName] interface method. +func (b *dualDBBuilder) QuoteSimpleTableName(table string) string { + return b.concurrentDB.QuoteSimpleTableName(table) +} + +// QuoteSimpleColumnName implements the [dbx.Builder.QuoteSimpleColumnName] interface method. +func (b *dualDBBuilder) QuoteSimpleColumnName(col string) string { + return b.concurrentDB.QuoteSimpleColumnName(col) +} + +// QueryBuilder implements the [dbx.Builder.QueryBuilder] interface method. +func (b *dualDBBuilder) QueryBuilder() dbx.QueryBuilder { + return b.concurrentDB.QueryBuilder() +} + +// Insert implements the [dbx.Builder.Insert] interface method. +func (b *dualDBBuilder) Insert(table string, cols dbx.Params) *dbx.Query { + return b.nonconcurrentDB.Insert(table, cols) +} + +// Upsert implements the [dbx.Builder.Upsert] interface method. +func (b *dualDBBuilder) Upsert(table string, cols dbx.Params, constraints ...string) *dbx.Query { + return b.nonconcurrentDB.Upsert(table, cols, constraints...) +} + +// Update implements the [dbx.Builder.Update] interface method. +func (b *dualDBBuilder) Update(table string, cols dbx.Params, where dbx.Expression) *dbx.Query { + return b.nonconcurrentDB.Update(table, cols, where) +} + +// Delete implements the [dbx.Builder.Delete] interface method. +func (b *dualDBBuilder) Delete(table string, where dbx.Expression) *dbx.Query { + return b.nonconcurrentDB.Delete(table, where) +} + +// CreateTable implements the [dbx.Builder.CreateTable] interface method. +func (b *dualDBBuilder) CreateTable(table string, cols map[string]string, options ...string) *dbx.Query { + return b.nonconcurrentDB.CreateTable(table, cols, options...) +} + +// RenameTable implements the [dbx.Builder.RenameTable] interface method. +func (b *dualDBBuilder) RenameTable(oldName, newName string) *dbx.Query { + return b.nonconcurrentDB.RenameTable(oldName, newName) +} + +// DropTable implements the [dbx.Builder.DropTable] interface method. +func (b *dualDBBuilder) DropTable(table string) *dbx.Query { + return b.nonconcurrentDB.DropTable(table) +} + +// TruncateTable implements the [dbx.Builder.TruncateTable] interface method. +func (b *dualDBBuilder) TruncateTable(table string) *dbx.Query { + return b.nonconcurrentDB.TruncateTable(table) +} + +// AddColumn implements the [dbx.Builder.AddColumn] interface method. +func (b *dualDBBuilder) AddColumn(table, col, typ string) *dbx.Query { + return b.nonconcurrentDB.AddColumn(table, col, typ) +} + +// DropColumn implements the [dbx.Builder.DropColumn] interface method. +func (b *dualDBBuilder) DropColumn(table, col string) *dbx.Query { + return b.nonconcurrentDB.DropColumn(table, col) +} + +// RenameColumn implements the [dbx.Builder.RenameColumn] interface method. +func (b *dualDBBuilder) RenameColumn(table, oldName, newName string) *dbx.Query { + return b.nonconcurrentDB.RenameColumn(table, oldName, newName) +} + +// AlterColumn implements the [dbx.Builder.AlterColumn] interface method. +func (b *dualDBBuilder) AlterColumn(table, col, typ string) *dbx.Query { + return b.nonconcurrentDB.AlterColumn(table, col, typ) +} + +// AddPrimaryKey implements the [dbx.Builder.AddPrimaryKey] interface method. +func (b *dualDBBuilder) AddPrimaryKey(table, name string, cols ...string) *dbx.Query { + return b.nonconcurrentDB.AddPrimaryKey(table, name, cols...) +} + +// DropPrimaryKey implements the [dbx.Builder.DropPrimaryKey] interface method. +func (b *dualDBBuilder) DropPrimaryKey(table, name string) *dbx.Query { + return b.nonconcurrentDB.DropPrimaryKey(table, name) +} + +// AddForeignKey implements the [dbx.Builder.AddForeignKey] interface method. +func (b *dualDBBuilder) AddForeignKey(table, name string, cols, refCols []string, refTable string, options ...string) *dbx.Query { + return b.nonconcurrentDB.AddForeignKey(table, name, cols, refCols, refTable, options...) +} + +// DropForeignKey implements the [dbx.Builder.DropForeignKey] interface method. +func (b *dualDBBuilder) DropForeignKey(table, name string) *dbx.Query { + return b.nonconcurrentDB.DropForeignKey(table, name) +} + +// CreateIndex implements the [dbx.Builder.CreateIndex] interface method. +func (b *dualDBBuilder) CreateIndex(table, name string, cols ...string) *dbx.Query { + return b.nonconcurrentDB.CreateIndex(table, name, cols...) +} + +// CreateUniqueIndex implements the [dbx.Builder.CreateUniqueIndex] interface method. +func (b *dualDBBuilder) CreateUniqueIndex(table, name string, cols ...string) *dbx.Query { + return b.nonconcurrentDB.CreateUniqueIndex(table, name, cols...) +} + +// DropIndex implements the [dbx.Builder.DropIndex] interface method. +func (b *dualDBBuilder) DropIndex(table, name string) *dbx.Query { + return b.nonconcurrentDB.DropIndex(table, name) +} + +// NewQuery implements the [dbx.Builder.NewQuery] interface method by +// routing the SELECT queries to the concurrent builder instance. +func (b *dualDBBuilder) NewQuery(str string) *dbx.Query { + // note: technically INSERT/UPDATE/DELETE could also have CTE but since + // it is rare for now this scase is ignored to avoid unnecessary complicating the checks + trimmed := trimLeftSpaces(str) + if hasPrefixFold(trimmed, "SELECT") || hasPrefixFold(trimmed, "WITH") { + return b.concurrentDB.NewQuery(str) + } + + return b.nonconcurrentDB.NewQuery(str) +} + +var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1} + +// note: similar to strings.Space() but without the right trim because it is not needed in our case +func trimLeftSpaces(str string) string { + start := 0 + for ; start < len(str); start++ { + c := str[start] + if c >= utf8.RuneSelf { + return strings.TrimLeftFunc(str[start:], unicode.IsSpace) + } + if asciiSpace[c] == 0 { + break + } + } + + return str[start:] +} + +// note: the prefix is expected to be ASCII +func hasPrefixFold(str, prefix string) bool { + if len(str) < len(prefix) { + return false + } + + return strings.EqualFold(str[:len(prefix)], prefix) +} diff --git a/core/db_table.go b/core/db_table.go index 332984b4..053c24bb 100644 --- a/core/db_table.go +++ b/core/db_table.go @@ -11,7 +11,7 @@ import ( func (app *BaseApp) TableColumns(tableName string) ([]string, error) { columns := []string{} - err := app.DB().NewQuery("SELECT name FROM PRAGMA_TABLE_INFO({:tableName})"). + err := app.ConcurrentDB().NewQuery("SELECT name FROM PRAGMA_TABLE_INFO({:tableName})"). Bind(dbx.Params{"tableName": tableName}). Column(&columns) @@ -34,7 +34,7 @@ type TableInfoRow struct { func (app *BaseApp) TableInfo(tableName string) ([]*TableInfoRow, error) { info := []*TableInfoRow{} - err := app.DB().NewQuery("SELECT * FROM PRAGMA_TABLE_INFO({:tableName})"). + err := app.ConcurrentDB().NewQuery("SELECT * FROM PRAGMA_TABLE_INFO({:tableName})"). Bind(dbx.Params{"tableName": tableName}). All(&info) if err != nil { @@ -59,7 +59,7 @@ func (app *BaseApp) TableIndexes(tableName string) (map[string]string, error) { Sql string }{} - err := app.DB().Select("name", "sql"). + err := app.ConcurrentDB().Select("name", "sql"). From("sqlite_master"). AndWhere(dbx.NewExp("sql is not null")). AndWhere(dbx.HashExp{ @@ -87,7 +87,7 @@ func (app *BaseApp) TableIndexes(tableName string) (map[string]string, error) { // NB! Be aware that this method is vulnerable to SQL injection and the // "tableName" argument must come only from trusted input! func (app *BaseApp) DeleteTable(tableName string) error { - _, err := app.DB().NewQuery(fmt.Sprintf( + _, err := app.NonconcurrentDB().NewQuery(fmt.Sprintf( "DROP TABLE IF EXISTS {{%s}}", tableName, )).Execute() @@ -96,15 +96,15 @@ func (app *BaseApp) DeleteTable(tableName string) error { } // HasTable checks if a table (or view) with the provided name exists (case insensitive). -// in the current app.DB() instance. +// in the data.db. func (app *BaseApp) HasTable(tableName string) bool { - return app.hasTable(app.DB(), tableName) + return app.hasTable(app.ConcurrentDB(), tableName) } // AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) -// in the current app.AuxDB() instance. +// in the auixiliary.db. func (app *BaseApp) AuxHasTable(tableName string) bool { - return app.hasTable(app.AuxDB(), tableName) + return app.hasTable(app.AuxConcurrentDB(), tableName) } func (app *BaseApp) hasTable(db dbx.Builder, tableName string) bool { @@ -120,16 +120,14 @@ func (app *BaseApp) hasTable(db dbx.Builder, tableName string) bool { return err == nil && exists > 0 } -// Vacuum executes VACUUM on the current app.DB() instance -// in order to reclaim unused data db disk space. +// Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. func (app *BaseApp) Vacuum() error { - return app.vacuum(app.DB()) + return app.vacuum(app.NonconcurrentDB()) } -// AuxVacuum executes VACUUM on the current app.AuxDB() instance -// in order to reclaim unused auxiliary db disk space. +// AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. func (app *BaseApp) AuxVacuum() error { - return app.vacuum(app.AuxDB()) + return app.vacuum(app.AuxNonconcurrentDB()) } func (app *BaseApp) vacuum(db dbx.Builder) error { diff --git a/core/db_table_test.go b/core/db_table_test.go index 1b9a7cc8..2dede6be 100644 --- a/core/db_table_test.go +++ b/core/db_table_test.go @@ -202,10 +202,10 @@ func TestVacuum(t *testing.T) { defer app.Cleanup() calledQueries := []string{} - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { calledQueries = append(calledQueries, sql) } - app.DB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { calledQueries = append(calledQueries, sql) } @@ -229,10 +229,10 @@ func TestAuxVacuum(t *testing.T) { defer app.Cleanup() calledQueries := []string{} - app.AuxDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + app.AuxNonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { calledQueries = append(calledQueries, sql) } - app.AuxDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + app.AuxNonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { calledQueries = append(calledQueries, sql) } diff --git a/core/db_test.go b/core/db_test.go index 2dc30998..d274b7ef 100644 --- a/core/db_test.go +++ b/core/db_test.go @@ -38,12 +38,12 @@ func TestModelQuery(t *testing.T) { modelsQuery := app.ModelQuery(&core.Collection{}) logsModelQuery := app.AuxModelQuery(&core.Collection{}) - if app.DB() == modelsQuery.Info().Builder { - t.Fatalf("ModelQuery() is not using app.DB()") + if app.ConcurrentDB() == modelsQuery.Info().Builder { + t.Fatalf("ModelQuery() is not using app.ConcurrentDB()") } - if app.AuxDB() == logsModelQuery.Info().Builder { - t.Fatalf("AuxModelQuery() is not using app.AuxDB()") + if app.AuxConcurrentDB() == logsModelQuery.Info().Builder { + t.Fatalf("AuxModelQuery() is not using app.AuxConcurrentDB()") } expectedSQL := "SELECT {{_collections}}.* FROM `_collections`" diff --git a/core/external_auth_query_test.go b/core/external_auth_query_test.go index eaf51d00..868ba665 100644 --- a/core/external_auth_query_test.go +++ b/core/external_auth_query_test.go @@ -155,7 +155,7 @@ func TestFindFirstExternalAuthByExpr(t *testing.T) { } for i, s := range scenarios { - t.Run(fmt.Sprintf("%d_%v", i, s.expr.Build(app.DB().(*dbx.DB), dbx.Params{})), func(t *testing.T) { + t.Run(fmt.Sprintf("%d_%v", i, s.expr.Build(app.ConcurrentDB().(*dbx.DB), dbx.Params{})), func(t *testing.T) { result, err := app.FindFirstExternalAuthByExpr(s.expr) hasErr := err != nil diff --git a/core/field_file.go b/core/field_file.go index 39db7ebb..871adebb 100644 --- a/core/field_file.go +++ b/core/field_file.go @@ -10,7 +10,6 @@ import ( "strings" validation "github.com/go-ozzo/ozzo-validation/v4" - "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core/validators" "github.com/pocketbase/pocketbase/tools/filesystem" "github.com/pocketbase/pocketbase/tools/list" @@ -357,8 +356,7 @@ func (f *FileField) Intercept( return nil case InterceptorActionAfterCreateError, InterceptorActionAfterUpdateError: // when in transaction we assume that the error was handled by afterRecordExecuteFailure - _, insideTransaction := app.DB().(*dbx.Tx) - if insideTransaction { + if app.IsTransactional() { return actionFunc() } diff --git a/core/field_relation.go b/core/field_relation.go index 54d6f350..77956457 100644 --- a/core/field_relation.go +++ b/core/field_relation.go @@ -219,7 +219,7 @@ func (f *RelationField) ValidateValue(ctx context.Context, app App, record *Reco } var total int - _ = app.DB(). + _ = app.ConcurrentDB(). Select("count(*)"). From(relCollection.Name). AndWhere(dbx.In("id", list.ToInterfaceSlice(ids)...)). diff --git a/core/field_text.go b/core/field_text.go index 2e4ad82a..b999e8b1 100644 --- a/core/field_text.go +++ b/core/field_text.go @@ -194,7 +194,7 @@ func (f *TextField) ValidateValue(ctx context.Context, app App, record *Record) // (@todo eventually may get replaced in the future with a system unique constraint to avoid races or wrapping the request in a transaction) if f.Pattern != defaultLowercaseRecordIdPattern { var exists int - err := app.DB(). + err := app.ConcurrentDB(). Select("(1)"). From(record.TableName()). Where(dbx.NewExp("id = {:id} COLLATE NOCASE", dbx.Params{"id": newVal})). diff --git a/core/log_printer_test.go b/core/log_printer_test.go index 35a660d4..43497495 100644 --- a/core/log_printer_test.go +++ b/core/log_printer_test.go @@ -55,10 +55,10 @@ func TestBaseAppLoggerLevelDevPrint(t *testing.T) { } // silence query logs - app.DB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} - app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} - app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} + app.concurrentDB.(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} + app.concurrentDB.(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} + app.nonconcurrentDB.(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} + app.nonconcurrentDB.(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} app.Settings().Logs.MinLevel = testLogLevel if err := app.Save(app.Settings()); err != nil { diff --git a/core/record_model_test.go b/core/record_model_test.go index d597be0b..e469b46c 100644 --- a/core/record_model_test.go +++ b/core/record_model_test.go @@ -2254,13 +2254,13 @@ func TestRecordDelete(t *testing.T) { app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { calledQueries = append(calledQueries, sql) } - app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { + app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) { calledQueries = append(calledQueries, sql) } app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { calledQueries = append(calledQueries, sql) } - app.DB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { + app.ConcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) { calledQueries = append(calledQueries, sql) } rec3, _ := app.FindRecordById("users", "oap640cot4yru2s") diff --git a/core/record_query.go b/core/record_query.go index 28b54ccc..9797ca1f 100644 --- a/core/record_query.go +++ b/core/record_query.go @@ -35,7 +35,7 @@ func (app *BaseApp) RecordQuery(collectionModelOrIdentifier any) *dbx.SelectQuer tableName = "@@__invalidCollectionModelOrIdentifier" } - query := app.DB().Select(app.DB().QuoteSimpleColumnName(tableName) + ".*").From(tableName) + query := app.ConcurrentDB().Select(app.ConcurrentDB().QuoteSimpleColumnName(tableName) + ".*").From(tableName) // in case of an error attach a new context and cancel it immediately with the error if collectionErr != nil { diff --git a/core/record_query_expand.go b/core/record_query_expand.go index 04fc016a..2869c1da 100644 --- a/core/record_query_expand.go +++ b/core/record_query_expand.go @@ -103,7 +103,7 @@ func (app *BaseApp) expandRecords(records []*Record, expandPath string, fetchFun // add the related id(s) as a dynamic relation field value to // allow further expand checks at later stage in a more unified manner prepErr := func() error { - q := app.DB().Select("id"). + q := app.ConcurrentDB().Select("id"). From(indirectRel.Name). Limit(1000) // the limit is arbitrary chosen and may change in the future diff --git a/forms/record_upsert.go b/forms/record_upsert.go index dd7ea40e..02b65089 100644 --- a/forms/record_upsert.go +++ b/forms/record_upsert.go @@ -227,7 +227,7 @@ func (form *RecordUpsert) DrySubmit(callback func(txApp core.App, drySavedRecord app := form.app.UnsafeWithoutHooks() - _, isTransactional := app.DB().(*dbx.Tx) + isTransactional := app.IsTransactional() if !isTransactional { return app.RunInTransaction(func(txApp core.App) error { tx, ok := txApp.DB().(*dbx.Tx) diff --git a/plugins/jsvm/internal/types/generated/types.d.ts b/plugins/jsvm/internal/types/generated/types.d.ts index 33eced11..8615dd7a 100644 --- a/plugins/jsvm/internal/types/generated/types.d.ts +++ b/plugins/jsvm/internal/types/generated/types.d.ts @@ -1,4 +1,4 @@ -// 1745760764 +// 1746163067 // GENERATED CODE - DO NOT MODIFY BY HAND // ------------------------------------------------------------------- @@ -1770,8 +1770,8 @@ namespace os { * than ReadFrom. This is used to permit ReadFrom to call io.Copy * without leading to a recursive call to ReadFrom. */ - type _sdCELnk = noReadFrom&File - interface fileWithoutReadFrom extends _sdCELnk { + type _scXFvOp = noReadFrom&File + interface fileWithoutReadFrom extends _scXFvOp { } interface File { /** @@ -1815,8 +1815,8 @@ namespace os { * than WriteTo. This is used to permit WriteTo to call io.Copy * without leading to a recursive call to WriteTo. */ - type _sCrddIM = noWriteTo&File - interface fileWithoutWriteTo extends _sCrddIM { + type _sYyYqpf = noWriteTo&File + interface fileWithoutWriteTo extends _sYyYqpf { } interface File { /** @@ -2460,8 +2460,8 @@ namespace os { * * The methods of File are safe for concurrent use. */ - type _sCVCvgh = file - interface File extends _sCVCvgh { + type _sNtBkgi = file + interface File extends _sNtBkgi { } /** * A FileInfo describes a file and is returned by [Stat] and [Lstat]. @@ -2853,6 +2853,149 @@ namespace filepath { } } +namespace security { + interface s256Challenge { + /** + * S256Challenge creates base64 encoded sha256 challenge string derived from code. + * The padding of the result base64 string is stripped per [RFC 7636]. + * + * [RFC 7636]: https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 + */ + (code: string): string + } + interface md5 { + /** + * MD5 creates md5 hash from the provided plain text. + */ + (text: string): string + } + interface sha256 { + /** + * SHA256 creates sha256 hash as defined in FIPS 180-4 from the provided text. + */ + (text: string): string + } + interface sha512 { + /** + * SHA512 creates sha512 hash as defined in FIPS 180-4 from the provided text. + */ + (text: string): string + } + interface hs256 { + /** + * HS256 creates a HMAC hash with sha256 digest algorithm. + */ + (text: string, secret: string): string + } + interface hs512 { + /** + * HS512 creates a HMAC hash with sha512 digest algorithm. + */ + (text: string, secret: string): string + } + interface equal { + /** + * Equal compares two hash strings for equality without leaking timing information. + */ + (hash1: string, hash2: string): boolean + } + // @ts-ignore + import crand = rand + interface encrypt { + /** + * Encrypt encrypts "data" with the specified "key" (must be valid 32 char AES key). + * + * This method uses AES-256-GCM block cypher mode. + */ + (data: string|Array, key: string): string + } + interface decrypt { + /** + * Decrypt decrypts encrypted text with key (must be valid 32 chars AES key). + * + * This method uses AES-256-GCM block cypher mode. + */ + (cipherText: string, key: string): string|Array + } + interface parseUnverifiedJWT { + /** + * ParseUnverifiedJWT parses JWT and returns its claims + * but DOES NOT verify the signature. + * + * It verifies only the exp, iat and nbf claims. + */ + (token: string): jwt.MapClaims + } + interface parseJWT { + /** + * ParseJWT verifies and parses JWT and returns its claims. + */ + (token: string, verificationKey: string): jwt.MapClaims + } + interface newJWT { + /** + * NewJWT generates and returns new HS256 signed JWT. + */ + (payload: jwt.MapClaims, signingKey: string, duration: time.Duration): string + } + // @ts-ignore + import cryptoRand = rand + // @ts-ignore + import mathRand = rand + interface randomString { + /** + * RandomString generates a cryptographically random string with the specified length. + * + * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. + */ + (length: number): string + } + interface randomStringWithAlphabet { + /** + * RandomStringWithAlphabet generates a cryptographically random string + * with the specified length and characters set. + * + * It panics if for some reason rand.Int returns a non-nil error. + */ + (length: number, alphabet: string): string + } + interface pseudorandomString { + /** + * PseudorandomString generates a pseudorandom string with the specified length. + * + * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. + * + * For a cryptographically random string (but a little bit slower) use RandomString instead. + */ + (length: number): string + } + interface pseudorandomStringWithAlphabet { + /** + * PseudorandomStringWithAlphabet generates a pseudorandom string + * with the specified length and characters set. + * + * For a cryptographically random (but a little bit slower) use RandomStringWithAlphabet instead. + */ + (length: number, alphabet: string): string + } + interface randomStringByRegex { + /** + * RandomStringByRegex generates a random string matching the regex pattern. + * If optFlags is not set, fallbacks to [syntax.Perl]. + * + * NB! While the source of the randomness comes from [crypto/rand] this method + * is not recommended to be used on its own in critical secure contexts because + * the generated length could vary too much on the used pattern and may not be + * as secure as simply calling [security.RandomString]. + * If you still insist on using it for such purposes, consider at least + * a large enough minimum length for the generated string, e.g. `[a-z0-9]{30}`. + * + * This function is inspired by github.com/pipe01/revregexp, github.com/lucasjones/reggen and other similar packages. + */ + (pattern: string, ...optFlags: syntax.Flags[]): string + } +} + /** * Package validation provides configurable and extensible rules for validating data of various types. */ @@ -3207,14 +3350,14 @@ namespace dbx { /** * MssqlBuilder is the builder for SQL Server databases. */ - type _sTtynvA = BaseBuilder - interface MssqlBuilder extends _sTtynvA { + type _sqDAAAt = BaseBuilder + interface MssqlBuilder extends _sqDAAAt { } /** * MssqlQueryBuilder is the query builder for SQL Server databases. */ - type _sePiHru = BaseQueryBuilder - interface MssqlQueryBuilder extends _sePiHru { + type _sVJPnyI = BaseQueryBuilder + interface MssqlQueryBuilder extends _sVJPnyI { } interface newMssqlBuilder { /** @@ -3285,8 +3428,8 @@ namespace dbx { /** * MysqlBuilder is the builder for MySQL databases. */ - type _seQjkaw = BaseBuilder - interface MysqlBuilder extends _seQjkaw { + type _sDbmRGb = BaseBuilder + interface MysqlBuilder extends _sDbmRGb { } interface newMysqlBuilder { /** @@ -3361,14 +3504,14 @@ namespace dbx { /** * OciBuilder is the builder for Oracle databases. */ - type _sxqjsSo = BaseBuilder - interface OciBuilder extends _sxqjsSo { + type _sUwxIau = BaseBuilder + interface OciBuilder extends _sUwxIau { } /** * OciQueryBuilder is the query builder for Oracle databases. */ - type _sRxFaAW = BaseQueryBuilder - interface OciQueryBuilder extends _sRxFaAW { + type _sEuyqFm = BaseQueryBuilder + interface OciQueryBuilder extends _sEuyqFm { } interface newOciBuilder { /** @@ -3431,8 +3574,8 @@ namespace dbx { /** * PgsqlBuilder is the builder for PostgreSQL databases. */ - type _szFmmPT = BaseBuilder - interface PgsqlBuilder extends _szFmmPT { + type _szbfUgv = BaseBuilder + interface PgsqlBuilder extends _szbfUgv { } interface newPgsqlBuilder { /** @@ -3499,8 +3642,8 @@ namespace dbx { /** * SqliteBuilder is the builder for SQLite databases. */ - type _sAjAujC = BaseBuilder - interface SqliteBuilder extends _sAjAujC { + type _sbhbgSj = BaseBuilder + interface SqliteBuilder extends _sbhbgSj { } interface newSqliteBuilder { /** @@ -3599,8 +3742,8 @@ namespace dbx { /** * StandardBuilder is the builder that is used by DB for an unknown driver. */ - type _sKZidQM = BaseBuilder - interface StandardBuilder extends _sKZidQM { + type _sDbfMMZ = BaseBuilder + interface StandardBuilder extends _sDbfMMZ { } interface newStandardBuilder { /** @@ -3666,8 +3809,8 @@ namespace dbx { * DB enhances sql.DB by providing a set of DB-agnostic query building methods. * DB allows easier query building and population of data into Go variables. */ - type _sxXYiUS = Builder - interface DB extends _sxXYiUS { + type _sSaBpsw = Builder + interface DB extends _sSaBpsw { /** * FieldMapper maps struct fields to DB columns. Defaults to DefaultFieldMapFunc. */ @@ -4471,8 +4614,8 @@ namespace dbx { * Rows enhances sql.Rows by providing additional data query methods. * Rows can be obtained by calling Query.Rows(). It is mainly used to populate data row by row. */ - type _scTavaK = sql.Rows - interface Rows extends _scTavaK { + type _sHUpGhw = sql.Rows + interface Rows extends _sHUpGhw { } interface Rows { /** @@ -4844,8 +4987,8 @@ namespace dbx { }): string } interface structInfo { } - type _sVmqVvg = structInfo - interface structValue extends _sVmqVvg { + type _sMpdkBr = structInfo + interface structValue extends _sMpdkBr { } interface fieldInfo { } @@ -4884,8 +5027,8 @@ namespace dbx { /** * Tx enhances sql.Tx with additional querying methods. */ - type _svaXvPe = Builder - interface Tx extends _svaXvPe { + type _sWkxVMV = Builder + interface Tx extends _sWkxVMV { } interface Tx { /** @@ -4901,149 +5044,6 @@ namespace dbx { } } -namespace security { - interface s256Challenge { - /** - * S256Challenge creates base64 encoded sha256 challenge string derived from code. - * The padding of the result base64 string is stripped per [RFC 7636]. - * - * [RFC 7636]: https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 - */ - (code: string): string - } - interface md5 { - /** - * MD5 creates md5 hash from the provided plain text. - */ - (text: string): string - } - interface sha256 { - /** - * SHA256 creates sha256 hash as defined in FIPS 180-4 from the provided text. - */ - (text: string): string - } - interface sha512 { - /** - * SHA512 creates sha512 hash as defined in FIPS 180-4 from the provided text. - */ - (text: string): string - } - interface hs256 { - /** - * HS256 creates a HMAC hash with sha256 digest algorithm. - */ - (text: string, secret: string): string - } - interface hs512 { - /** - * HS512 creates a HMAC hash with sha512 digest algorithm. - */ - (text: string, secret: string): string - } - interface equal { - /** - * Equal compares two hash strings for equality without leaking timing information. - */ - (hash1: string, hash2: string): boolean - } - // @ts-ignore - import crand = rand - interface encrypt { - /** - * Encrypt encrypts "data" with the specified "key" (must be valid 32 char AES key). - * - * This method uses AES-256-GCM block cypher mode. - */ - (data: string|Array, key: string): string - } - interface decrypt { - /** - * Decrypt decrypts encrypted text with key (must be valid 32 chars AES key). - * - * This method uses AES-256-GCM block cypher mode. - */ - (cipherText: string, key: string): string|Array - } - interface parseUnverifiedJWT { - /** - * ParseUnverifiedJWT parses JWT and returns its claims - * but DOES NOT verify the signature. - * - * It verifies only the exp, iat and nbf claims. - */ - (token: string): jwt.MapClaims - } - interface parseJWT { - /** - * ParseJWT verifies and parses JWT and returns its claims. - */ - (token: string, verificationKey: string): jwt.MapClaims - } - interface newJWT { - /** - * NewJWT generates and returns new HS256 signed JWT. - */ - (payload: jwt.MapClaims, signingKey: string, duration: time.Duration): string - } - // @ts-ignore - import cryptoRand = rand - // @ts-ignore - import mathRand = rand - interface randomString { - /** - * RandomString generates a cryptographically random string with the specified length. - * - * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. - */ - (length: number): string - } - interface randomStringWithAlphabet { - /** - * RandomStringWithAlphabet generates a cryptographically random string - * with the specified length and characters set. - * - * It panics if for some reason rand.Int returns a non-nil error. - */ - (length: number, alphabet: string): string - } - interface pseudorandomString { - /** - * PseudorandomString generates a pseudorandom string with the specified length. - * - * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. - * - * For a cryptographically random string (but a little bit slower) use RandomString instead. - */ - (length: number): string - } - interface pseudorandomStringWithAlphabet { - /** - * PseudorandomStringWithAlphabet generates a pseudorandom string - * with the specified length and characters set. - * - * For a cryptographically random (but a little bit slower) use RandomStringWithAlphabet instead. - */ - (length: number, alphabet: string): string - } - interface randomStringByRegex { - /** - * RandomStringByRegex generates a random string matching the regex pattern. - * If optFlags is not set, fallbacks to [syntax.Perl]. - * - * NB! While the source of the randomness comes from [crypto/rand] this method - * is not recommended to be used on its own in critical secure contexts because - * the generated length could vary too much on the used pattern and may not be - * as secure as simply calling [security.RandomString]. - * If you still insist on using it for such purposes, consider at least - * a large enough minimum length for the generated string, e.g. `[a-z0-9]{30}`. - * - * This function is inspired by github.com/pipe01/revregexp, github.com/lucasjones/reggen and other similar packages. - */ - (pattern: string, ...optFlags: syntax.Flags[]): string - } -} - namespace filesystem { /** * FileReader defines an interface for a file resource reader. @@ -5140,8 +5140,8 @@ namespace filesystem { */ open(): io.ReadSeekCloser } - type _sqEUkuG = bytes.Reader - interface bytesReadSeekCloser extends _sqEUkuG { + type _sfpFTpR = bytes.Reader + interface bytesReadSeekCloser extends _sfpFTpR { } interface bytesReadSeekCloser { /** @@ -5200,6 +5200,8 @@ namespace filesystem { * NB! Make sure to call Close() on the file after you are done working with it. * * If the file doesn't exist returns ErrNotFound. + * + * @todo consider renaming to GetFileReader to avoid the confusion with filesystem.File */ getFile(fileKey: string): (blob.Reader) } @@ -5578,51 +5580,89 @@ namespace core { */ runAllMigrations(): void /** - * DB returns the default app data db instance (pb_data/data.db). + * DB returns the default app data.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything else + * to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly ConcurrentDB() or NonconcurrentDB(). */ db(): dbx.Builder /** - * NonconcurrentDB returns the nonconcurrent app data db instance (pb_data/data.db). + * ConcurrentDB returns the concurrent app data.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + concurrentDB(): dbx.Builder + /** + * NonconcurrentDB returns the nonconcurrent app data.db builder instance. * * The returned db instance is limited only to a single open connection, - * meaning that it can process only 1 db operation at a time (other operations will be queued up). + * meaning that it can process only 1 db operation at a time (other queries queue up). * * This method is used mainly internally and in the tests to execute write * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. * - * For the majority of cases you would want to use the regular DB() method - * since it allows concurrent db read operations. + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). * * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. */ nonconcurrentDB(): dbx.Builder /** - * AuxDB returns the default app auxiliary db instance (pb_data/auxiliary.db). + * AuxDB returns the app auxiliary.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything else + * to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly AuxConcurrentDB() or AuxNonconcurrentDB(). */ auxDB(): dbx.Builder /** - * AuxNonconcurrentDB returns the nonconcurrent app auxiliary db instance (pb_data/auxiliary.db).. + * AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxConcurrentDB(): dbx.Builder + /** + * AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. * * The returned db instance is limited only to a single open connection, - * meaning that it can process only 1 db operation at a time (other operations will be queued up). + * meaning that it can process only 1 db operation at a time (other queries queue up). * * This method is used mainly internally and in the tests to execute write * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. * - * For the majority of cases you would want to use the regular DB() method - * since it allows concurrent db read operations. + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). * - * In a transaction the AuxNonconcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. */ auxNonconcurrentDB(): dbx.Builder /** * HasTable checks if a table (or view) with the provided name exists (case insensitive). - * in the current app.DB() instance. + * in the data.db. */ hasTable(tableName: string): boolean /** * AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) - * in the current app.AuxDB() instance. + * in the auxiliary.db. */ auxHasTable(tableName: string): boolean /** @@ -5677,22 +5717,20 @@ namespace core { */ findRecordByViewFile(viewCollectionModelOrIdentifier: any, fileFieldName: string, filename: string): (Record) /** - * Vacuum executes VACUUM on the current app.DB() instance - * in order to reclaim unused data db disk space. + * Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. */ vacuum(): void /** - * AuxVacuum executes VACUUM on the current app.AuxDB() instance - * in order to reclaim unused auxiliary db disk space. + * AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. */ auxVacuum(): void /** - * ModelQuery creates a new preconfigured select app.DB() query with preset + * ModelQuery creates a new preconfigured select data.db query with preset * SELECT, FROM and other common fields based on the provided model. */ modelQuery(model: Model): (dbx.SelectQuery) /** - * AuxModelQuery creates a new preconfigured select app.AuxDB() query with preset + * AuxModelQuery creates a new preconfigured select auxiliary.db query with preset * SELECT, FROM and other common fields based on the provided model. */ auxModelQuery(model: Model): (dbx.SelectQuery) @@ -7038,8 +7076,8 @@ namespace core { /** * AuthOrigin defines a Record proxy for working with the authOrigins collection. */ - type _sfRwmij = Record - interface AuthOrigin extends _sfRwmij { + type _sJAFMZQ = Record + interface AuthOrigin extends _sJAFMZQ { } interface newAuthOrigin { /** @@ -7261,22 +7299,43 @@ namespace core { } interface BaseApp { /** - * DB returns the default app data db instance (pb_data/data.db). + * DB returns the default app data.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything + * else to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly ConcurrentDB() or NonconcurrentDB(). */ db(): dbx.Builder } interface BaseApp { /** - * NonconcurrentDB returns the nonconcurrent app data db instance (pb_data/data.db). + * ConcurrentDB returns the concurrent app data.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + concurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * NonconcurrentDB returns the nonconcurrent app data.db builder instance. * * The returned db instance is limited only to a single open connection, - * meaning that it can process only 1 db operation at a time (other operations will be queued up). + * meaning that it can process only 1 db operation at a time (other queries queue up). * * This method is used mainly internally and in the tests to execute write * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. * - * For the majority of cases you would want to use the regular DB() method - * since it allows concurrent db read operations. + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). * * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. */ @@ -7284,24 +7343,45 @@ namespace core { } interface BaseApp { /** - * AuxDB returns the default app auxiliary db instance (pb_data/auxiliary.db). + * AuxDB returns the app auxiliary.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything + * else to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly AuxConcurrentDB() or AuxNonconcurrentDB(). */ auxDB(): dbx.Builder } interface BaseApp { /** - * AuxNonconcurrentDB returns the nonconcurrent app auxiliary db instance (pb_data/auxiliary.db). + * AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxConcurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. * * The returned db instance is limited only to a single open connection, - * meaning that it can process only 1 db operation at a time (other operations will be queued up). + * meaning that it can process only 1 db operation at a time (other queries queue up). * * This method is used mainly internally and in the tests to execute write * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. * - * For the majority of cases you would want to use the regular DB() method - * since it allows concurrent db read operations. + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). * - * In a transaction the AuxNonconcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. */ auxNonconcurrentDB(): dbx.Builder } @@ -7742,8 +7822,8 @@ namespace core { /** * @todo experiment eventually replacing the rules *string with a struct? */ - type _sfEvgZi = BaseModel - interface baseCollection extends _sfEvgZi { + type _suNNncV = BaseModel + interface baseCollection extends _suNNncV { listRule?: string viewRule?: string createRule?: string @@ -7770,8 +7850,8 @@ namespace core { /** * Collection defines the table, fields and various options related to a set of records. */ - type _szoaowL = baseCollection&collectionAuthOptions&collectionViewOptions - interface Collection extends _szoaowL { + type _smObuGw = baseCollection&collectionAuthOptions&collectionViewOptions + interface Collection extends _smObuGw { } interface newCollection { /** @@ -8325,14 +8405,14 @@ namespace core { } interface BaseApp { /** - * ModelQuery creates a new preconfigured select app.DB() query with preset + * ModelQuery creates a new preconfigured select data.db query with preset * SELECT, FROM and other common fields based on the provided model. */ modelQuery(m: Model): (dbx.SelectQuery) } interface BaseApp { /** - * AuxModelQuery creates a new preconfigured select app.AuxDB() query with preset + * AuxModelQuery creates a new preconfigured select auxiliary.db query with preset * SELECT, FROM and other common fields based on the provided model. */ auxModelQuery(m: Model): (dbx.SelectQuery) @@ -8441,6 +8521,175 @@ namespace core { */ validateWithContext(ctx: context.Context, model: Model): void } + /** + * note: expects both builder to use the same driver + */ + interface dualDBBuilder { + } + interface dualDBBuilder { + /** + * Select implements the [dbx.Builder.Select] interface method. + */ + select(...cols: string[]): (dbx.SelectQuery) + } + interface dualDBBuilder { + /** + * Model implements the [dbx.Builder.Model] interface method. + */ + model(data: { + }): (dbx.ModelQuery) + } + interface dualDBBuilder { + /** + * GeneratePlaceholder implements the [dbx.Builder.GeneratePlaceholder] interface method. + */ + generatePlaceholder(i: number): string + } + interface dualDBBuilder { + /** + * Quote implements the [dbx.Builder.Quote] interface method. + */ + quote(str: string): string + } + interface dualDBBuilder { + /** + * QuoteSimpleTableName implements the [dbx.Builder.QuoteSimpleTableName] interface method. + */ + quoteSimpleTableName(table: string): string + } + interface dualDBBuilder { + /** + * QuoteSimpleColumnName implements the [dbx.Builder.QuoteSimpleColumnName] interface method. + */ + quoteSimpleColumnName(col: string): string + } + interface dualDBBuilder { + /** + * QueryBuilder implements the [dbx.Builder.QueryBuilder] interface method. + */ + queryBuilder(): dbx.QueryBuilder + } + interface dualDBBuilder { + /** + * Insert implements the [dbx.Builder.Insert] interface method. + */ + insert(table: string, cols: dbx.Params): (dbx.Query) + } + interface dualDBBuilder { + /** + * Upsert implements the [dbx.Builder.Upsert] interface method. + */ + upsert(table: string, cols: dbx.Params, ...constraints: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * Update implements the [dbx.Builder.Update] interface method. + */ + update(table: string, cols: dbx.Params, where: dbx.Expression): (dbx.Query) + } + interface dualDBBuilder { + /** + * Delete implements the [dbx.Builder.Delete] interface method. + */ + delete(table: string, where: dbx.Expression): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateTable implements the [dbx.Builder.CreateTable] interface method. + */ + createTable(table: string, cols: _TygojaDict, ...options: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * RenameTable implements the [dbx.Builder.RenameTable] interface method. + */ + renameTable(oldName: string, newName: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropTable implements the [dbx.Builder.DropTable] interface method. + */ + dropTable(table: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * TruncateTable implements the [dbx.Builder.TruncateTable] interface method. + */ + truncateTable(table: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddColumn implements the [dbx.Builder.AddColumn] interface method. + */ + addColumn(table: string, col: string, typ: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropColumn implements the [dbx.Builder.DropColumn] interface method. + */ + dropColumn(table: string, col: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * RenameColumn implements the [dbx.Builder.RenameColumn] interface method. + */ + renameColumn(table: string, oldName: string, newName: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AlterColumn implements the [dbx.Builder.AlterColumn] interface method. + */ + alterColumn(table: string, col: string, typ: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddPrimaryKey implements the [dbx.Builder.AddPrimaryKey] interface method. + */ + addPrimaryKey(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropPrimaryKey implements the [dbx.Builder.DropPrimaryKey] interface method. + */ + dropPrimaryKey(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddForeignKey implements the [dbx.Builder.AddForeignKey] interface method. + */ + addForeignKey(table: string, name: string, cols: Array, refCols: Array, refTable: string, ...options: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropForeignKey implements the [dbx.Builder.DropForeignKey] interface method. + */ + dropForeignKey(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateIndex implements the [dbx.Builder.CreateIndex] interface method. + */ + createIndex(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateUniqueIndex implements the [dbx.Builder.CreateUniqueIndex] interface method. + */ + createUniqueIndex(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropIndex implements the [dbx.Builder.DropIndex] interface method. + */ + dropIndex(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * NewQuery implements the [dbx.Builder.NewQuery] interface method by + * routing the SELECT queries to the concurrent builder instance. + */ + newQuery(str: string): (dbx.Query) + } interface defaultDBConnect { (dbPath: string): (dbx.DB) } @@ -8554,28 +8803,26 @@ namespace core { interface BaseApp { /** * HasTable checks if a table (or view) with the provided name exists (case insensitive). - * in the current app.DB() instance. + * in the data.db. */ hasTable(tableName: string): boolean } interface BaseApp { /** * AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) - * in the current app.AuxDB() instance. + * in the auixiliary.db. */ auxHasTable(tableName: string): boolean } interface BaseApp { /** - * Vacuum executes VACUUM on the current app.DB() instance - * in order to reclaim unused data db disk space. + * Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. */ vacuum(): void } interface BaseApp { /** - * AuxVacuum executes VACUUM on the current app.AuxDB() instance - * in order to reclaim unused auxiliary db disk space. + * AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. */ auxVacuum(): void } @@ -8614,8 +8861,8 @@ namespace core { /** * RequestEvent defines the PocketBase router handler event. */ - type _sYFAbjG = router.Event - interface RequestEvent extends _sYFAbjG { + type _sXVXRXf = router.Event + interface RequestEvent extends _sXVXRXf { app: App auth?: Record } @@ -8675,8 +8922,8 @@ namespace core { */ clone(): (RequestInfo) } - type _sElPQrW = hook.Event&RequestEvent - interface BatchRequestEvent extends _sElPQrW { + type _sbhrVGw = hook.Event&RequestEvent + interface BatchRequestEvent extends _sbhrVGw { batch: Array<(InternalRequest | undefined)> } interface InternalRequest { @@ -8713,24 +8960,24 @@ namespace core { interface baseCollectionEventData { tags(): Array } - type _sdKOEvl = hook.Event - interface BootstrapEvent extends _sdKOEvl { + type _sXkAsiS = hook.Event + interface BootstrapEvent extends _sXkAsiS { app: App } - type _snbmgIU = hook.Event - interface TerminateEvent extends _snbmgIU { + type _sJoMtFO = hook.Event + interface TerminateEvent extends _sJoMtFO { app: App isRestart: boolean } - type _sPnzVur = hook.Event - interface BackupEvent extends _sPnzVur { + type _sRGQYAJ = hook.Event + interface BackupEvent extends _sRGQYAJ { app: App context: context.Context name: string // the name of the backup to create/restore. exclude: Array // list of dir entries to exclude from the backup create/restore. } - type _suRDMBR = hook.Event - interface ServeEvent extends _suRDMBR { + type _stmGOkt = hook.Event + interface ServeEvent extends _stmGOkt { app: App router?: router.Router server?: http.Server @@ -8753,31 +9000,31 @@ namespace core { */ installerFunc: (app: App, systemSuperuser: Record, baseURL: string) => void } - type _sANhoNI = hook.Event&RequestEvent - interface SettingsListRequestEvent extends _sANhoNI { + type _sMqzwfZ = hook.Event&RequestEvent + interface SettingsListRequestEvent extends _sMqzwfZ { settings?: Settings } - type _sxuuXiM = hook.Event&RequestEvent - interface SettingsUpdateRequestEvent extends _sxuuXiM { + type _sHHsrMU = hook.Event&RequestEvent + interface SettingsUpdateRequestEvent extends _sHHsrMU { oldSettings?: Settings newSettings?: Settings } - type _sDCPXoB = hook.Event - interface SettingsReloadEvent extends _sDCPXoB { + type _spIxdyB = hook.Event + interface SettingsReloadEvent extends _spIxdyB { app: App } - type _sPWexsU = hook.Event - interface MailerEvent extends _sPWexsU { + type _shIZySB = hook.Event + interface MailerEvent extends _shIZySB { app: App mailer: mailer.Mailer message?: mailer.Message } - type _sFUVdFG = MailerEvent&baseRecordEventData - interface MailerRecordEvent extends _sFUVdFG { + type _sFhzkjJ = MailerEvent&baseRecordEventData + interface MailerRecordEvent extends _sFhzkjJ { meta: _TygojaDict } - type _sBBJwGA = hook.Event&baseModelEventData - interface ModelEvent extends _sBBJwGA { + type _sqrpTUF = hook.Event&baseModelEventData + interface ModelEvent extends _sqrpTUF { app: App context: context.Context /** @@ -8789,12 +9036,12 @@ namespace core { */ type: string } - type _syrIMcY = ModelEvent - interface ModelErrorEvent extends _syrIMcY { + type _sUFUVuw = ModelEvent + interface ModelErrorEvent extends _sUFUVuw { error: Error } - type _sGSMqxu = hook.Event&baseRecordEventData - interface RecordEvent extends _sGSMqxu { + type _syhAAlx = hook.Event&baseRecordEventData + interface RecordEvent extends _syhAAlx { app: App context: context.Context /** @@ -8806,12 +9053,12 @@ namespace core { */ type: string } - type _sFxjfbD = RecordEvent - interface RecordErrorEvent extends _sFxjfbD { + type _sbATDYW = RecordEvent + interface RecordErrorEvent extends _sbATDYW { error: Error } - type _sQqDGJp = hook.Event&baseCollectionEventData - interface CollectionEvent extends _sQqDGJp { + type _sFWyGxH = hook.Event&baseCollectionEventData + interface CollectionEvent extends _sFWyGxH { app: App context: context.Context /** @@ -8823,95 +9070,95 @@ namespace core { */ type: string } - type _sLDmjZk = CollectionEvent - interface CollectionErrorEvent extends _sLDmjZk { + type _sfuxKvF = CollectionEvent + interface CollectionErrorEvent extends _sfuxKvF { error: Error } - type _sCCKIbq = hook.Event&RequestEvent&baseRecordEventData - interface FileTokenRequestEvent extends _sCCKIbq { + type _szTVEJQ = hook.Event&RequestEvent&baseRecordEventData + interface FileTokenRequestEvent extends _szTVEJQ { token: string } - type _sAKHMbZ = hook.Event&RequestEvent&baseCollectionEventData - interface FileDownloadRequestEvent extends _sAKHMbZ { + type _svQmJOi = hook.Event&RequestEvent&baseCollectionEventData + interface FileDownloadRequestEvent extends _svQmJOi { record?: Record fileField?: FileField servedPath: string servedName: string } - type _sPcZqGn = hook.Event&RequestEvent - interface CollectionsListRequestEvent extends _sPcZqGn { + type _sYvegGA = hook.Event&RequestEvent + interface CollectionsListRequestEvent extends _sYvegGA { collections: Array<(Collection | undefined)> result?: search.Result } - type _sqiGJgx = hook.Event&RequestEvent - interface CollectionsImportRequestEvent extends _sqiGJgx { + type _sbeTtLq = hook.Event&RequestEvent + interface CollectionsImportRequestEvent extends _sbeTtLq { collectionsData: Array<_TygojaDict> deleteMissing: boolean } - type _sHPxUvD = hook.Event&RequestEvent&baseCollectionEventData - interface CollectionRequestEvent extends _sHPxUvD { + type _sbDeBxd = hook.Event&RequestEvent&baseCollectionEventData + interface CollectionRequestEvent extends _sbDeBxd { } - type _skTeSII = hook.Event&RequestEvent - interface RealtimeConnectRequestEvent extends _skTeSII { + type _sOwVbSK = hook.Event&RequestEvent + interface RealtimeConnectRequestEvent extends _sOwVbSK { client: subscriptions.Client /** * note: modifying it after the connect has no effect */ idleTimeout: time.Duration } - type _sCajqWA = hook.Event&RequestEvent - interface RealtimeMessageEvent extends _sCajqWA { + type _sxwFsny = hook.Event&RequestEvent + interface RealtimeMessageEvent extends _sxwFsny { client: subscriptions.Client message?: subscriptions.Message } - type _sPSRtKe = hook.Event&RequestEvent - interface RealtimeSubscribeRequestEvent extends _sPSRtKe { + type _ssLWIEs = hook.Event&RequestEvent + interface RealtimeSubscribeRequestEvent extends _ssLWIEs { client: subscriptions.Client subscriptions: Array } - type _sAtNxBJ = hook.Event&RequestEvent&baseCollectionEventData - interface RecordsListRequestEvent extends _sAtNxBJ { + type _scMSBby = hook.Event&RequestEvent&baseCollectionEventData + interface RecordsListRequestEvent extends _scMSBby { /** * @todo consider removing and maybe add as generic to the search.Result? */ records: Array<(Record | undefined)> result?: search.Result } - type _sKvuFEX = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestEvent extends _sKvuFEX { + type _sqGuRmp = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEvent extends _sqGuRmp { record?: Record } - type _sjEEdUJ = hook.Event&baseRecordEventData - interface RecordEnrichEvent extends _sjEEdUJ { + type _sWKUmEu = hook.Event&baseRecordEventData + interface RecordEnrichEvent extends _sWKUmEu { app: App requestInfo?: RequestInfo } - type _sKOuwqw = hook.Event&RequestEvent&baseCollectionEventData - interface RecordCreateOTPRequestEvent extends _sKOuwqw { + type _sBBiBWg = hook.Event&RequestEvent&baseCollectionEventData + interface RecordCreateOTPRequestEvent extends _sBBiBWg { record?: Record password: string } - type _sSXFSMv = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithOTPRequestEvent extends _sSXFSMv { + type _sXSAsSB = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOTPRequestEvent extends _sXSAsSB { record?: Record otp?: OTP } - type _sMDxJev = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthRequestEvent extends _sMDxJev { + type _sCsLOmc = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRequestEvent extends _sCsLOmc { record?: Record token: string meta: any authMethod: string } - type _sEAaMsO = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithPasswordRequestEvent extends _sEAaMsO { + type _sJeOmhI = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithPasswordRequestEvent extends _sJeOmhI { record?: Record identity: string identityField: string password: string } - type _scEgrmH = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithOAuth2RequestEvent extends _scEgrmH { + type _sDlEMzY = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOAuth2RequestEvent extends _sDlEMzY { providerName: string providerClient: auth.Provider record?: Record @@ -8919,41 +9166,41 @@ namespace core { createData: _TygojaDict isNewRecord: boolean } - type _shKFWlP = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthRefreshRequestEvent extends _shKFWlP { + type _spHEtzL = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRefreshRequestEvent extends _spHEtzL { record?: Record } - type _seYYvAL = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestPasswordResetRequestEvent extends _seYYvAL { + type _sdbaOPs = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestPasswordResetRequestEvent extends _sdbaOPs { record?: Record } - type _sifoqtg = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmPasswordResetRequestEvent extends _sifoqtg { + type _spxDiZc = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmPasswordResetRequestEvent extends _spxDiZc { record?: Record } - type _sFgEXkp = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestVerificationRequestEvent extends _sFgEXkp { + type _sLwrtye = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestVerificationRequestEvent extends _sLwrtye { record?: Record } - type _sCWPuzi = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmVerificationRequestEvent extends _sCWPuzi { + type _sZNUHnO = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmVerificationRequestEvent extends _sZNUHnO { record?: Record } - type _snqMQuI = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestEmailChangeRequestEvent extends _snqMQuI { + type _spZyaGr = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEmailChangeRequestEvent extends _spZyaGr { record?: Record newEmail: string } - type _shuGoxr = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmEmailChangeRequestEvent extends _shuGoxr { + type _senFmMh = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmEmailChangeRequestEvent extends _senFmMh { record?: Record newEmail: string } /** * ExternalAuth defines a Record proxy for working with the externalAuths collection. */ - type _sWMXOnK = Record - interface ExternalAuth extends _sWMXOnK { + type _syktXxD = Record + interface ExternalAuth extends _syktXxD { } interface newExternalAuth { /** @@ -11415,8 +11662,8 @@ namespace core { interface onlyFieldType { type: string } - type _sOAklvy = Field - interface fieldWithType extends _sOAklvy { + type _sOcNmwL = Field + interface fieldWithType extends _sOcNmwL { type: string } interface fieldWithType { @@ -11448,8 +11695,8 @@ namespace core { */ scan(value: any): void } - type _sETPqQz = BaseModel - interface Log extends _sETPqQz { + type _sLeXNFk = BaseModel + interface Log extends _sLeXNFk { created: types.DateTime data: types.JSONMap message: string @@ -11495,8 +11742,8 @@ namespace core { /** * MFA defines a Record proxy for working with the mfas collection. */ - type _skytbAc = Record - interface MFA extends _skytbAc { + type _sNoQoFW = Record + interface MFA extends _sNoQoFW { } interface newMFA { /** @@ -11718,8 +11965,8 @@ namespace core { /** * OTP defines a Record proxy for working with the otps collection. */ - type _sUhTHaE = Record - interface OTP extends _sUhTHaE { + type _stjCSsU = Record + interface OTP extends _stjCSsU { } interface newOTP { /** @@ -11955,8 +12202,8 @@ namespace core { } interface runner { } - type _smdCVvt = BaseModel - interface Record extends _smdCVvt { + type _sLmKNes = BaseModel + interface Record extends _sLmKNes { } interface newRecord { /** @@ -12431,8 +12678,8 @@ namespace core { * BaseRecordProxy implements the [RecordProxy] interface and it is intended * to be used as embed to custom user provided Record proxy structs. */ - type _sKWmpwd = Record - interface BaseRecordProxy extends _sKWmpwd { + type _seUTizl = Record + interface BaseRecordProxy extends _seUTizl { } interface BaseRecordProxy { /** @@ -12681,8 +12928,8 @@ namespace core { /** * Settings defines the PocketBase app settings. */ - type _sgriuPf = settings - interface Settings extends _sgriuPf { + type _sCNTvJb = settings + interface Settings extends _sCNTvJb { } interface Settings { /** @@ -12983,8 +13230,8 @@ namespace core { */ durationTime(): time.Duration } - type _sQmHncJ = BaseModel - interface Param extends _sQmHncJ { + type _sxTZTQO = BaseModel + interface Param extends _sxTZTQO { created: types.DateTime updated: types.DateTime value: types.JSONRaw @@ -13498,8 +13745,8 @@ namespace apis { */ (limitBytes: number): (hook.Handler) } - type _sDFgYLn = io.ReadCloser - interface limitedReader extends _sDFgYLn { + type _swYJPMI = io.ReadCloser + interface limitedReader extends _swYJPMI { } interface limitedReader { read(b: string|Array): number @@ -13650,8 +13897,8 @@ namespace apis { */ (config: GzipConfig): (hook.Handler) } - type _sgDWKaC = http.ResponseWriter&io.Writer - interface gzipResponseWriter extends _sgDWKaC { + type _sxMaaBK = http.ResponseWriter&io.Writer + interface gzipResponseWriter extends _sxMaaBK { } interface gzipResponseWriter { writeHeader(code: number): void @@ -13671,11 +13918,11 @@ namespace apis { interface gzipResponseWriter { unwrap(): http.ResponseWriter } - type _sApSNQV = sync.RWMutex - interface rateLimiter extends _sApSNQV { + type _syMkqrf = sync.RWMutex + interface rateLimiter extends _syMkqrf { } - type _sjehlQw = sync.Mutex - interface fixedWindow extends _sjehlQw { + type _sYfzFoU = sync.Mutex + interface fixedWindow extends _sYfzFoU { } interface realtimeSubscribeForm { clientId: string @@ -13909,6 +14156,99 @@ namespace apis { } } +namespace pocketbase { + /** + * PocketBase defines a PocketBase app launcher. + * + * It implements [CoreApp] via embedding and all of the app interface methods + * could be accessed directly through the instance (eg. PocketBase.DataDir()). + */ + type _sztmgnp = CoreApp + interface PocketBase extends _sztmgnp { + /** + * RootCmd is the main console command + */ + rootCmd?: cobra.Command + } + /** + * Config is the PocketBase initialization config struct. + */ + interface Config { + /** + * hide the default console server info on app startup + */ + hideStartBanner: boolean + /** + * optional default values for the console flags + */ + defaultDev: boolean + defaultDataDir: string // if not set, it will fallback to "./pb_data" + defaultEncryptionEnv: string + defaultQueryTimeout: time.Duration // default to core.DefaultQueryTimeout (in seconds) + /** + * optional DB configurations + */ + dataMaxOpenConns: number // default to core.DefaultDataMaxOpenConns + dataMaxIdleConns: number // default to core.DefaultDataMaxIdleConns + auxMaxOpenConns: number // default to core.DefaultAuxMaxOpenConns + auxMaxIdleConns: number // default to core.DefaultAuxMaxIdleConns + dbConnect: core.DBConnectFunc // default to core.dbConnect + } + interface _new { + /** + * New creates a new PocketBase instance with the default configuration. + * Use [NewWithConfig] if you want to provide a custom configuration. + * + * Note that the application will not be initialized/bootstrapped yet, + * aka. DB connections, migrations, app settings, etc. will not be accessible. + * Everything will be initialized when [PocketBase.Start] is executed. + * If you want to initialize the application before calling [PocketBase.Start], + * then you'll have to manually call [PocketBase.Bootstrap]. + */ + (): (PocketBase) + } + interface newWithConfig { + /** + * NewWithConfig creates a new PocketBase instance with the provided config. + * + * Note that the application will not be initialized/bootstrapped yet, + * aka. DB connections, migrations, app settings, etc. will not be accessible. + * Everything will be initialized when [PocketBase.Start] is executed. + * If you want to initialize the application before calling [PocketBase.Start], + * then you'll have to manually call [PocketBase.Bootstrap]. + */ + (config: Config): (PocketBase) + } + interface PocketBase { + /** + * Start starts the application, aka. registers the default system + * commands (serve, superuser, version) and executes pb.RootCmd. + */ + start(): void + } + interface PocketBase { + /** + * Execute initializes the application (if not already) and executes + * the pb.RootCmd with graceful shutdown support. + * + * This method differs from pb.Start() by not registering the default + * system commands! + */ + execute(): void + } + /** + * coloredWriter is a small wrapper struct to construct a [color.Color] writter. + */ + interface coloredWriter { + } + interface coloredWriter { + /** + * Write writes the p bytes using the colored writer. + */ + write(p: string|Array): number + } +} + /** * Package template is a thin wrapper around the standard html/template * and text/template packages that implements a convenient registry to @@ -14014,99 +14354,6 @@ namespace template { } } -namespace pocketbase { - /** - * PocketBase defines a PocketBase app launcher. - * - * It implements [CoreApp] via embedding and all of the app interface methods - * could be accessed directly through the instance (eg. PocketBase.DataDir()). - */ - type _soCqXOr = CoreApp - interface PocketBase extends _soCqXOr { - /** - * RootCmd is the main console command - */ - rootCmd?: cobra.Command - } - /** - * Config is the PocketBase initialization config struct. - */ - interface Config { - /** - * hide the default console server info on app startup - */ - hideStartBanner: boolean - /** - * optional default values for the console flags - */ - defaultDev: boolean - defaultDataDir: string // if not set, it will fallback to "./pb_data" - defaultEncryptionEnv: string - defaultQueryTimeout: time.Duration // default to core.DefaultQueryTimeout (in seconds) - /** - * optional DB configurations - */ - dataMaxOpenConns: number // default to core.DefaultDataMaxOpenConns - dataMaxIdleConns: number // default to core.DefaultDataMaxIdleConns - auxMaxOpenConns: number // default to core.DefaultAuxMaxOpenConns - auxMaxIdleConns: number // default to core.DefaultAuxMaxIdleConns - dbConnect: core.DBConnectFunc // default to core.dbConnect - } - interface _new { - /** - * New creates a new PocketBase instance with the default configuration. - * Use [NewWithConfig] if you want to provide a custom configuration. - * - * Note that the application will not be initialized/bootstrapped yet, - * aka. DB connections, migrations, app settings, etc. will not be accessible. - * Everything will be initialized when [PocketBase.Start] is executed. - * If you want to initialize the application before calling [PocketBase.Start], - * then you'll have to manually call [PocketBase.Bootstrap]. - */ - (): (PocketBase) - } - interface newWithConfig { - /** - * NewWithConfig creates a new PocketBase instance with the provided config. - * - * Note that the application will not be initialized/bootstrapped yet, - * aka. DB connections, migrations, app settings, etc. will not be accessible. - * Everything will be initialized when [PocketBase.Start] is executed. - * If you want to initialize the application before calling [PocketBase.Start], - * then you'll have to manually call [PocketBase.Bootstrap]. - */ - (config: Config): (PocketBase) - } - interface PocketBase { - /** - * Start starts the application, aka. registers the default system - * commands (serve, superuser, version) and executes pb.RootCmd. - */ - start(): void - } - interface PocketBase { - /** - * Execute initializes the application (if not already) and executes - * the pb.RootCmd with graceful shutdown support. - * - * This method differs from pb.Start() by not registering the default - * system commands! - */ - execute(): void - } - /** - * coloredWriter is a small wrapper struct to construct a [color.Color] writter. - */ - interface coloredWriter { - } - interface coloredWriter { - /** - * Write writes the p bytes using the colored writer. - */ - write(p: string|Array): number - } -} - /** * Package sync provides basic synchronization primitives such as mutual * exclusion locks. Other than the [Once] and [WaitGroup] types, most are intended @@ -15150,169 +15397,6 @@ namespace time { } } -/** - * Package context defines the Context type, which carries deadlines, - * cancellation signals, and other request-scoped values across API boundaries - * and between processes. - * - * Incoming requests to a server should create a [Context], and outgoing - * calls to servers should accept a Context. The chain of function - * calls between them must propagate the Context, optionally replacing - * it with a derived Context created using [WithCancel], [WithDeadline], - * [WithTimeout], or [WithValue]. When a Context is canceled, all - * Contexts derived from it are also canceled. - * - * The [WithCancel], [WithDeadline], and [WithTimeout] functions take a - * Context (the parent) and return a derived Context (the child) and a - * [CancelFunc]. Calling the CancelFunc cancels the child and its - * children, removes the parent's reference to the child, and stops - * any associated timers. Failing to call the CancelFunc leaks the - * child and its children until the parent is canceled or the timer - * fires. The go vet tool checks that CancelFuncs are used on all - * control-flow paths. - * - * The [WithCancelCause] function returns a [CancelCauseFunc], which - * takes an error and records it as the cancellation cause. Calling - * [Cause] on the canceled context or any of its children retrieves - * the cause. If no cause is specified, Cause(ctx) returns the same - * value as ctx.Err(). - * - * Programs that use Contexts should follow these rules to keep interfaces - * consistent across packages and enable static analysis tools to check context - * propagation: - * - * Do not store Contexts inside a struct type; instead, pass a Context - * explicitly to each function that needs it. The Context should be the first - * parameter, typically named ctx: - * - * ``` - * func DoSomething(ctx context.Context, arg Arg) error { - * // ... use ctx ... - * } - * ``` - * - * Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] - * if you are unsure about which Context to use. - * - * Use context Values only for request-scoped data that transits processes and - * APIs, not for passing optional parameters to functions. - * - * The same Context may be passed to functions running in different goroutines; - * Contexts are safe for simultaneous use by multiple goroutines. - * - * See https://blog.golang.org/context for example code for a server that uses - * Contexts. - */ -namespace context { - /** - * A Context carries a deadline, a cancellation signal, and other values across - * API boundaries. - * - * Context's methods may be called by multiple goroutines simultaneously. - */ - interface Context { - [key:string]: any; - /** - * Deadline returns the time when work done on behalf of this context - * should be canceled. Deadline returns ok==false when no deadline is - * set. Successive calls to Deadline return the same results. - */ - deadline(): [time.Time, boolean] - /** - * Done returns a channel that's closed when work done on behalf of this - * context should be canceled. Done may return nil if this context can - * never be canceled. Successive calls to Done return the same value. - * The close of the Done channel may happen asynchronously, - * after the cancel function returns. - * - * WithCancel arranges for Done to be closed when cancel is called; - * WithDeadline arranges for Done to be closed when the deadline - * expires; WithTimeout arranges for Done to be closed when the timeout - * elapses. - * - * Done is provided for use in select statements: - * - * // Stream generates values with DoSomething and sends them to out - * // until DoSomething returns an error or ctx.Done is closed. - * func Stream(ctx context.Context, out chan<- Value) error { - * for { - * v, err := DoSomething(ctx) - * if err != nil { - * return err - * } - * select { - * case <-ctx.Done(): - * return ctx.Err() - * case out <- v: - * } - * } - * } - * - * See https://blog.golang.org/pipelines for more examples of how to use - * a Done channel for cancellation. - */ - done(): undefined - /** - * If Done is not yet closed, Err returns nil. - * If Done is closed, Err returns a non-nil error explaining why: - * Canceled if the context was canceled - * or DeadlineExceeded if the context's deadline passed. - * After Err returns a non-nil error, successive calls to Err return the same error. - */ - err(): void - /** - * Value returns the value associated with this context for key, or nil - * if no value is associated with key. Successive calls to Value with - * the same key returns the same result. - * - * Use context values only for request-scoped data that transits - * processes and API boundaries, not for passing optional parameters to - * functions. - * - * A key identifies a specific value in a Context. Functions that wish - * to store values in Context typically allocate a key in a global - * variable then use that key as the argument to context.WithValue and - * Context.Value. A key can be any type that supports equality; - * packages should define keys as an unexported type to avoid - * collisions. - * - * Packages that define a Context key should provide type-safe accessors - * for the values stored using that key: - * - * ``` - * // Package user defines a User type that's stored in Contexts. - * package user - * - * import "context" - * - * // User is the type of value stored in the Contexts. - * type User struct {...} - * - * // key is an unexported type for keys defined in this package. - * // This prevents collisions with keys defined in other packages. - * type key int - * - * // userKey is the key for user.User values in Contexts. It is - * // unexported; clients use user.NewContext and user.FromContext - * // instead of using this key directly. - * var userKey key - * - * // NewContext returns a new Context that carries value u. - * func NewContext(ctx context.Context, u *User) context.Context { - * return context.WithValue(ctx, userKey, u) - * } - * - * // FromContext returns the User value stored in ctx, if any. - * func FromContext(ctx context.Context) (*User, bool) { - * u, ok := ctx.Value(userKey).(*User) - * return u, ok - * } - * ``` - */ - value(key: any): any - } -} - /** * Package fs defines basic interfaces to a file system. * A file system can be provided by the host operating system @@ -15513,296 +15597,166 @@ namespace fs { interface WalkDirFunc {(path: string, d: DirEntry, err: Error): void } } -namespace exec { - /** - * Cmd represents an external command being prepared or run. - * - * A Cmd cannot be reused after calling its [Cmd.Run], [Cmd.Output] or [Cmd.CombinedOutput] - * methods. - */ - interface Cmd { - /** - * Path is the path of the command to run. - * - * This is the only field that must be set to a non-zero - * value. If Path is relative, it is evaluated relative - * to Dir. - */ - path: string - /** - * Args holds command line arguments, including the command as Args[0]. - * If the Args field is empty or nil, Run uses {Path}. - * - * In typical use, both Path and Args are set by calling Command. - */ - args: Array - /** - * Env specifies the environment of the process. - * Each entry is of the form "key=value". - * If Env is nil, the new process uses the current process's - * environment. - * If Env contains duplicate environment keys, only the last - * value in the slice for each duplicate key is used. - * As a special case on Windows, SYSTEMROOT is always added if - * missing and not explicitly set to the empty string. - */ - env: Array - /** - * Dir specifies the working directory of the command. - * If Dir is the empty string, Run runs the command in the - * calling process's current directory. - */ - dir: string - /** - * Stdin specifies the process's standard input. - * - * If Stdin is nil, the process reads from the null device (os.DevNull). - * - * If Stdin is an *os.File, the process's standard input is connected - * directly to that file. - * - * Otherwise, during the execution of the command a separate - * goroutine reads from Stdin and delivers that data to the command - * over a pipe. In this case, Wait does not complete until the goroutine - * stops copying, either because it has reached the end of Stdin - * (EOF or a read error), or because writing to the pipe returned an error, - * or because a nonzero WaitDelay was set and expired. - */ - stdin: io.Reader - /** - * Stdout and Stderr specify the process's standard output and error. - * - * If either is nil, Run connects the corresponding file descriptor - * to the null device (os.DevNull). - * - * If either is an *os.File, the corresponding output from the process - * is connected directly to that file. - * - * Otherwise, during the execution of the command a separate goroutine - * reads from the process over a pipe and delivers that data to the - * corresponding Writer. In this case, Wait does not complete until the - * goroutine reaches EOF or encounters an error or a nonzero WaitDelay - * expires. - * - * If Stdout and Stderr are the same writer, and have a type that can - * be compared with ==, at most one goroutine at a time will call Write. - */ - stdout: io.Writer - stderr: io.Writer - /** - * ExtraFiles specifies additional open files to be inherited by the - * new process. It does not include standard input, standard output, or - * standard error. If non-nil, entry i becomes file descriptor 3+i. - * - * ExtraFiles is not supported on Windows. - */ - extraFiles: Array<(os.File | undefined)> - /** - * SysProcAttr holds optional, operating system-specific attributes. - * Run passes it to os.StartProcess as the os.ProcAttr's Sys field. - */ - sysProcAttr?: syscall.SysProcAttr - /** - * Process is the underlying process, once started. - */ - process?: os.Process - /** - * ProcessState contains information about an exited process. - * If the process was started successfully, Wait or Run will - * populate its ProcessState when the command completes. - */ - processState?: os.ProcessState - err: Error // LookPath error, if any. - /** - * If Cancel is non-nil, the command must have been created with - * CommandContext and Cancel will be called when the command's - * Context is done. By default, CommandContext sets Cancel to - * call the Kill method on the command's Process. - * - * Typically a custom Cancel will send a signal to the command's - * Process, but it may instead take other actions to initiate cancellation, - * such as closing a stdin or stdout pipe or sending a shutdown request on a - * network socket. - * - * If the command exits with a success status after Cancel is - * called, and Cancel does not return an error equivalent to - * os.ErrProcessDone, then Wait and similar methods will return a non-nil - * error: either an error wrapping the one returned by Cancel, - * or the error from the Context. - * (If the command exits with a non-success status, or Cancel - * returns an error that wraps os.ErrProcessDone, Wait and similar methods - * continue to return the command's usual exit status.) - * - * If Cancel is set to nil, nothing will happen immediately when the command's - * Context is done, but a nonzero WaitDelay will still take effect. That may - * be useful, for example, to work around deadlocks in commands that do not - * support shutdown signals but are expected to always finish quickly. - * - * Cancel will not be called if Start returns a non-nil error. - */ - cancel: () => void - /** - * If WaitDelay is non-zero, it bounds the time spent waiting on two sources - * of unexpected delay in Wait: a child process that fails to exit after the - * associated Context is canceled, and a child process that exits but leaves - * its I/O pipes unclosed. - * - * The WaitDelay timer starts when either the associated Context is done or a - * call to Wait observes that the child process has exited, whichever occurs - * first. When the delay has elapsed, the command shuts down the child process - * and/or its I/O pipes. - * - * If the child process has failed to exit — perhaps because it ignored or - * failed to receive a shutdown signal from a Cancel function, or because no - * Cancel function was set — then it will be terminated using os.Process.Kill. - * - * Then, if the I/O pipes communicating with the child process are still open, - * those pipes are closed in order to unblock any goroutines currently blocked - * on Read or Write calls. - * - * If pipes are closed due to WaitDelay, no Cancel call has occurred, - * and the command has otherwise exited with a successful status, Wait and - * similar methods will return ErrWaitDelay instead of nil. - * - * If WaitDelay is zero (the default), I/O pipes will be read until EOF, - * which might not occur until orphaned subprocesses of the command have - * also closed their descriptors for the pipes. - */ - waitDelay: time.Duration - } - interface Cmd { - /** - * String returns a human-readable description of c. - * It is intended only for debugging. - * In particular, it is not suitable for use as input to a shell. - * The output of String may vary across Go releases. - */ - string(): string - } - interface Cmd { - /** - * Run starts the specified command and waits for it to complete. - * - * The returned error is nil if the command runs, has no problems - * copying stdin, stdout, and stderr, and exits with a zero exit - * status. - * - * If the command starts but does not complete successfully, the error is of - * type [*ExitError]. Other error types may be returned for other situations. - * - * If the calling goroutine has locked the operating system thread - * with [runtime.LockOSThread] and modified any inheritable OS-level - * thread state (for example, Linux or Plan 9 name spaces), the new - * process will inherit the caller's thread state. - */ - run(): void - } - interface Cmd { - /** - * Start starts the specified command but does not wait for it to complete. - * - * If Start returns successfully, the c.Process field will be set. - * - * After a successful call to Start the [Cmd.Wait] method must be called in - * order to release associated system resources. - */ - start(): void - } - interface Cmd { - /** - * Wait waits for the command to exit and waits for any copying to - * stdin or copying from stdout or stderr to complete. - * - * The command must have been started by [Cmd.Start]. - * - * The returned error is nil if the command runs, has no problems - * copying stdin, stdout, and stderr, and exits with a zero exit - * status. - * - * If the command fails to run or doesn't complete successfully, the - * error is of type [*ExitError]. Other error types may be - * returned for I/O problems. - * - * If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits - * for the respective I/O loop copying to or from the process to complete. - * - * Wait releases any resources associated with the [Cmd]. - */ - wait(): void - } - interface Cmd { - /** - * Output runs the command and returns its standard output. - * Any returned error will usually be of type [*ExitError]. - * If c.Stderr was nil, Output populates [ExitError.Stderr]. - */ - output(): string|Array - } - interface Cmd { - /** - * CombinedOutput runs the command and returns its combined standard - * output and standard error. - */ - combinedOutput(): string|Array - } - interface Cmd { - /** - * StdinPipe returns a pipe that will be connected to the command's - * standard input when the command starts. - * The pipe will be closed automatically after [Cmd.Wait] sees the command exit. - * A caller need only call Close to force the pipe to close sooner. - * For example, if the command being run will not exit until standard input - * is closed, the caller must close the pipe. - */ - stdinPipe(): io.WriteCloser - } - interface Cmd { - /** - * StdoutPipe returns a pipe that will be connected to the command's - * standard output when the command starts. - * - * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers - * need not close the pipe themselves. It is thus incorrect to call Wait - * before all reads from the pipe have completed. - * For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe. - * See the example for idiomatic usage. - */ - stdoutPipe(): io.ReadCloser - } - interface Cmd { - /** - * StderrPipe returns a pipe that will be connected to the command's - * standard error when the command starts. - * - * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers - * need not close the pipe themselves. It is thus incorrect to call Wait - * before all reads from the pipe have completed. - * For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe. - * See the StdoutPipe example for idiomatic usage. - */ - stderrPipe(): io.ReadCloser - } - interface Cmd { - /** - * Environ returns a copy of the environment in which the command would be run - * as it is currently configured. - */ - environ(): Array - } -} - /** - * Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer - * object, creating another object (Reader or Writer) that also implements - * the interface but provides buffering and some help for textual I/O. + * Package context defines the Context type, which carries deadlines, + * cancellation signals, and other request-scoped values across API boundaries + * and between processes. + * + * Incoming requests to a server should create a [Context], and outgoing + * calls to servers should accept a Context. The chain of function + * calls between them must propagate the Context, optionally replacing + * it with a derived Context created using [WithCancel], [WithDeadline], + * [WithTimeout], or [WithValue]. When a Context is canceled, all + * Contexts derived from it are also canceled. + * + * The [WithCancel], [WithDeadline], and [WithTimeout] functions take a + * Context (the parent) and return a derived Context (the child) and a + * [CancelFunc]. Calling the CancelFunc cancels the child and its + * children, removes the parent's reference to the child, and stops + * any associated timers. Failing to call the CancelFunc leaks the + * child and its children until the parent is canceled or the timer + * fires. The go vet tool checks that CancelFuncs are used on all + * control-flow paths. + * + * The [WithCancelCause] function returns a [CancelCauseFunc], which + * takes an error and records it as the cancellation cause. Calling + * [Cause] on the canceled context or any of its children retrieves + * the cause. If no cause is specified, Cause(ctx) returns the same + * value as ctx.Err(). + * + * Programs that use Contexts should follow these rules to keep interfaces + * consistent across packages and enable static analysis tools to check context + * propagation: + * + * Do not store Contexts inside a struct type; instead, pass a Context + * explicitly to each function that needs it. The Context should be the first + * parameter, typically named ctx: + * + * ``` + * func DoSomething(ctx context.Context, arg Arg) error { + * // ... use ctx ... + * } + * ``` + * + * Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] + * if you are unsure about which Context to use. + * + * Use context Values only for request-scoped data that transits processes and + * APIs, not for passing optional parameters to functions. + * + * The same Context may be passed to functions running in different goroutines; + * Contexts are safe for simultaneous use by multiple goroutines. + * + * See https://blog.golang.org/context for example code for a server that uses + * Contexts. */ -namespace bufio { +namespace context { /** - * ReadWriter stores pointers to a [Reader] and a [Writer]. - * It implements [io.ReadWriter]. + * A Context carries a deadline, a cancellation signal, and other values across + * API boundaries. + * + * Context's methods may be called by multiple goroutines simultaneously. */ - type _sMYyEuA = Reader&Writer - interface ReadWriter extends _sMYyEuA { + interface Context { + [key:string]: any; + /** + * Deadline returns the time when work done on behalf of this context + * should be canceled. Deadline returns ok==false when no deadline is + * set. Successive calls to Deadline return the same results. + */ + deadline(): [time.Time, boolean] + /** + * Done returns a channel that's closed when work done on behalf of this + * context should be canceled. Done may return nil if this context can + * never be canceled. Successive calls to Done return the same value. + * The close of the Done channel may happen asynchronously, + * after the cancel function returns. + * + * WithCancel arranges for Done to be closed when cancel is called; + * WithDeadline arranges for Done to be closed when the deadline + * expires; WithTimeout arranges for Done to be closed when the timeout + * elapses. + * + * Done is provided for use in select statements: + * + * // Stream generates values with DoSomething and sends them to out + * // until DoSomething returns an error or ctx.Done is closed. + * func Stream(ctx context.Context, out chan<- Value) error { + * for { + * v, err := DoSomething(ctx) + * if err != nil { + * return err + * } + * select { + * case <-ctx.Done(): + * return ctx.Err() + * case out <- v: + * } + * } + * } + * + * See https://blog.golang.org/pipelines for more examples of how to use + * a Done channel for cancellation. + */ + done(): undefined + /** + * If Done is not yet closed, Err returns nil. + * If Done is closed, Err returns a non-nil error explaining why: + * Canceled if the context was canceled + * or DeadlineExceeded if the context's deadline passed. + * After Err returns a non-nil error, successive calls to Err return the same error. + */ + err(): void + /** + * Value returns the value associated with this context for key, or nil + * if no value is associated with key. Successive calls to Value with + * the same key returns the same result. + * + * Use context values only for request-scoped data that transits + * processes and API boundaries, not for passing optional parameters to + * functions. + * + * A key identifies a specific value in a Context. Functions that wish + * to store values in Context typically allocate a key in a global + * variable then use that key as the argument to context.WithValue and + * Context.Value. A key can be any type that supports equality; + * packages should define keys as an unexported type to avoid + * collisions. + * + * Packages that define a Context key should provide type-safe accessors + * for the values stored using that key: + * + * ``` + * // Package user defines a User type that's stored in Contexts. + * package user + * + * import "context" + * + * // User is the type of value stored in the Contexts. + * type User struct {...} + * + * // key is an unexported type for keys defined in this package. + * // This prevents collisions with keys defined in other packages. + * type key int + * + * // userKey is the key for user.User values in Contexts. It is + * // unexported; clients use user.NewContext and user.FromContext + * // instead of using this key directly. + * var userKey key + * + * // NewContext returns a new Context that carries value u. + * func NewContext(ctx context.Context, u *User) context.Context { + * return context.WithValue(ctx, userKey, u) + * } + * + * // FromContext returns the User value stored in ctx, if any. + * func FromContext(ctx context.Context) (*User, bool) { + * u, ok := ctx.Value(userKey).(*User) + * return u, ok + * } + * ``` + */ + value(key: any): any } } @@ -15973,6 +15927,560 @@ namespace net { } } +/** + * Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html + * + * See README.md for more info. + */ +namespace jwt { + /** + * MapClaims is a claims type that uses the map[string]interface{} for JSON + * decoding. This is the default claims type if you don't supply one + */ + interface MapClaims extends _TygojaDict{} + interface MapClaims { + /** + * GetExpirationTime implements the Claims interface. + */ + getExpirationTime(): (NumericDate) + } + interface MapClaims { + /** + * GetNotBefore implements the Claims interface. + */ + getNotBefore(): (NumericDate) + } + interface MapClaims { + /** + * GetIssuedAt implements the Claims interface. + */ + getIssuedAt(): (NumericDate) + } + interface MapClaims { + /** + * GetAudience implements the Claims interface. + */ + getAudience(): ClaimStrings + } + interface MapClaims { + /** + * GetIssuer implements the Claims interface. + */ + getIssuer(): string + } + interface MapClaims { + /** + * GetSubject implements the Claims interface. + */ + getSubject(): string + } +} + +/** + * Package slog provides structured logging, + * in which log records include a message, + * a severity level, and various other attributes + * expressed as key-value pairs. + * + * It defines a type, [Logger], + * which provides several methods (such as [Logger.Info] and [Logger.Error]) + * for reporting events of interest. + * + * Each Logger is associated with a [Handler]. + * A Logger output method creates a [Record] from the method arguments + * and passes it to the Handler, which decides how to handle it. + * There is a default Logger accessible through top-level functions + * (such as [Info] and [Error]) that call the corresponding Logger methods. + * + * A log record consists of a time, a level, a message, and a set of key-value + * pairs, where the keys are strings and the values may be of any type. + * As an example, + * + * ``` + * slog.Info("hello", "count", 3) + * ``` + * + * creates a record containing the time of the call, + * a level of Info, the message "hello", and a single + * pair with key "count" and value 3. + * + * The [Info] top-level function calls the [Logger.Info] method on the default Logger. + * In addition to [Logger.Info], there are methods for Debug, Warn and Error levels. + * Besides these convenience methods for common levels, + * there is also a [Logger.Log] method which takes the level as an argument. + * Each of these methods has a corresponding top-level function that uses the + * default logger. + * + * The default handler formats the log record's message, time, level, and attributes + * as a string and passes it to the [log] package. + * + * ``` + * 2022/11/08 15:28:26 INFO hello count=3 + * ``` + * + * For more control over the output format, create a logger with a different handler. + * This statement uses [New] to create a new logger with a [TextHandler] + * that writes structured records in text form to standard error: + * + * ``` + * logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) + * ``` + * + * [TextHandler] output is a sequence of key=value pairs, easily and unambiguously + * parsed by machine. This statement: + * + * ``` + * logger.Info("hello", "count", 3) + * ``` + * + * produces this output: + * + * ``` + * time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3 + * ``` + * + * The package also provides [JSONHandler], whose output is line-delimited JSON: + * + * ``` + * logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + * logger.Info("hello", "count", 3) + * ``` + * + * produces this output: + * + * ``` + * {"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3} + * ``` + * + * Both [TextHandler] and [JSONHandler] can be configured with [HandlerOptions]. + * There are options for setting the minimum level (see Levels, below), + * displaying the source file and line of the log call, and + * modifying attributes before they are logged. + * + * Setting a logger as the default with + * + * ``` + * slog.SetDefault(logger) + * ``` + * + * will cause the top-level functions like [Info] to use it. + * [SetDefault] also updates the default logger used by the [log] package, + * so that existing applications that use [log.Printf] and related functions + * will send log records to the logger's handler without needing to be rewritten. + * + * Some attributes are common to many log calls. + * For example, you may wish to include the URL or trace identifier of a server request + * with all log events arising from the request. + * Rather than repeat the attribute with every log call, you can use [Logger.With] + * to construct a new Logger containing the attributes: + * + * ``` + * logger2 := logger.With("url", r.URL) + * ``` + * + * The arguments to With are the same key-value pairs used in [Logger.Info]. + * The result is a new Logger with the same handler as the original, but additional + * attributes that will appear in the output of every call. + * + * # Levels + * + * A [Level] is an integer representing the importance or severity of a log event. + * The higher the level, the more severe the event. + * This package defines constants for the most common levels, + * but any int can be used as a level. + * + * In an application, you may wish to log messages only at a certain level or greater. + * One common configuration is to log messages at Info or higher levels, + * suppressing debug logging until it is needed. + * The built-in handlers can be configured with the minimum level to output by + * setting [HandlerOptions.Level]. + * The program's `main` function typically does this. + * The default value is LevelInfo. + * + * Setting the [HandlerOptions.Level] field to a [Level] value + * fixes the handler's minimum level throughout its lifetime. + * Setting it to a [LevelVar] allows the level to be varied dynamically. + * A LevelVar holds a Level and is safe to read or write from multiple + * goroutines. + * To vary the level dynamically for an entire program, first initialize + * a global LevelVar: + * + * ``` + * var programLevel = new(slog.LevelVar) // Info by default + * ``` + * + * Then use the LevelVar to construct a handler, and make it the default: + * + * ``` + * h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel}) + * slog.SetDefault(slog.New(h)) + * ``` + * + * Now the program can change its logging level with a single statement: + * + * ``` + * programLevel.Set(slog.LevelDebug) + * ``` + * + * # Groups + * + * Attributes can be collected into groups. + * A group has a name that is used to qualify the names of its attributes. + * How this qualification is displayed depends on the handler. + * [TextHandler] separates the group and attribute names with a dot. + * [JSONHandler] treats each group as a separate JSON object, with the group name as the key. + * + * Use [Group] to create a Group attribute from a name and a list of key-value pairs: + * + * ``` + * slog.Group("request", + * "method", r.Method, + * "url", r.URL) + * ``` + * + * TextHandler would display this group as + * + * ``` + * request.method=GET request.url=http://example.com + * ``` + * + * JSONHandler would display it as + * + * ``` + * "request":{"method":"GET","url":"http://example.com"} + * ``` + * + * Use [Logger.WithGroup] to qualify all of a Logger's output + * with a group name. Calling WithGroup on a Logger results in a + * new Logger with the same Handler as the original, but with all + * its attributes qualified by the group name. + * + * This can help prevent duplicate attribute keys in large systems, + * where subsystems might use the same keys. + * Pass each subsystem a different Logger with its own group name so that + * potential duplicates are qualified: + * + * ``` + * logger := slog.Default().With("id", systemID) + * parserLogger := logger.WithGroup("parser") + * parseInput(input, parserLogger) + * ``` + * + * When parseInput logs with parserLogger, its keys will be qualified with "parser", + * so even if it uses the common key "id", the log line will have distinct keys. + * + * # Contexts + * + * Some handlers may wish to include information from the [context.Context] that is + * available at the call site. One example of such information + * is the identifier for the current span when tracing is enabled. + * + * The [Logger.Log] and [Logger.LogAttrs] methods take a context as a first + * argument, as do their corresponding top-level functions. + * + * Although the convenience methods on Logger (Info and so on) and the + * corresponding top-level functions do not take a context, the alternatives ending + * in "Context" do. For example, + * + * ``` + * slog.InfoContext(ctx, "message") + * ``` + * + * It is recommended to pass a context to an output method if one is available. + * + * # Attrs and Values + * + * An [Attr] is a key-value pair. The Logger output methods accept Attrs as well as + * alternating keys and values. The statement + * + * ``` + * slog.Info("hello", slog.Int("count", 3)) + * ``` + * + * behaves the same as + * + * ``` + * slog.Info("hello", "count", 3) + * ``` + * + * There are convenience constructors for [Attr] such as [Int], [String], and [Bool] + * for common types, as well as the function [Any] for constructing Attrs of any + * type. + * + * The value part of an Attr is a type called [Value]. + * Like an [any], a Value can hold any Go value, + * but it can represent typical values, including all numbers and strings, + * without an allocation. + * + * For the most efficient log output, use [Logger.LogAttrs]. + * It is similar to [Logger.Log] but accepts only Attrs, not alternating + * keys and values; this allows it, too, to avoid allocation. + * + * The call + * + * ``` + * logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3)) + * ``` + * + * is the most efficient way to achieve the same output as + * + * ``` + * slog.InfoContext(ctx, "hello", "count", 3) + * ``` + * + * # Customizing a type's logging behavior + * + * If a type implements the [LogValuer] interface, the [Value] returned from its LogValue + * method is used for logging. You can use this to control how values of the type + * appear in logs. For example, you can redact secret information like passwords, + * or gather a struct's fields in a Group. See the examples under [LogValuer] for + * details. + * + * A LogValue method may return a Value that itself implements [LogValuer]. The [Value.Resolve] + * method handles these cases carefully, avoiding infinite loops and unbounded recursion. + * Handler authors and others may wish to use [Value.Resolve] instead of calling LogValue directly. + * + * # Wrapping output methods + * + * The logger functions use reflection over the call stack to find the file name + * and line number of the logging call within the application. This can produce + * incorrect source information for functions that wrap slog. For instance, if you + * define this function in file mylog.go: + * + * ``` + * func Infof(logger *slog.Logger, format string, args ...any) { + * logger.Info(fmt.Sprintf(format, args...)) + * } + * ``` + * + * and you call it like this in main.go: + * + * ``` + * Infof(slog.Default(), "hello, %s", "world") + * ``` + * + * then slog will report the source file as mylog.go, not main.go. + * + * A correct implementation of Infof will obtain the source location + * (pc) and pass it to NewRecord. + * The Infof function in the package-level example called "wrapping" + * demonstrates how to do this. + * + * # Working with Records + * + * Sometimes a Handler will need to modify a Record + * before passing it on to another Handler or backend. + * A Record contains a mixture of simple public fields (e.g. Time, Level, Message) + * and hidden fields that refer to state (such as attributes) indirectly. This + * means that modifying a simple copy of a Record (e.g. by calling + * [Record.Add] or [Record.AddAttrs] to add attributes) + * may have unexpected effects on the original. + * Before modifying a Record, use [Record.Clone] to + * create a copy that shares no state with the original, + * or create a new Record with [NewRecord] + * and build up its Attrs by traversing the old ones with [Record.Attrs]. + * + * # Performance considerations + * + * If profiling your application demonstrates that logging is taking significant time, + * the following suggestions may help. + * + * If many log lines have a common attribute, use [Logger.With] to create a Logger with + * that attribute. The built-in handlers will format that attribute only once, at the + * call to [Logger.With]. The [Handler] interface is designed to allow that optimization, + * and a well-written Handler should take advantage of it. + * + * The arguments to a log call are always evaluated, even if the log event is discarded. + * If possible, defer computation so that it happens only if the value is actually logged. + * For example, consider the call + * + * ``` + * slog.Info("starting request", "url", r.URL.String()) // may compute String unnecessarily + * ``` + * + * The URL.String method will be called even if the logger discards Info-level events. + * Instead, pass the URL directly: + * + * ``` + * slog.Info("starting request", "url", &r.URL) // calls URL.String only if needed + * ``` + * + * The built-in [TextHandler] will call its String method, but only + * if the log event is enabled. + * Avoiding the call to String also preserves the structure of the underlying value. + * For example [JSONHandler] emits the components of the parsed URL as a JSON object. + * If you want to avoid eagerly paying the cost of the String call + * without causing the handler to potentially inspect the structure of the value, + * wrap the value in a fmt.Stringer implementation that hides its Marshal methods. + * + * You can also use the [LogValuer] interface to avoid unnecessary work in disabled log + * calls. Say you need to log some expensive value: + * + * ``` + * slog.Debug("frobbing", "value", computeExpensiveValue(arg)) + * ``` + * + * Even if this line is disabled, computeExpensiveValue will be called. + * To avoid that, define a type implementing LogValuer: + * + * ``` + * type expensive struct { arg int } + * + * func (e expensive) LogValue() slog.Value { + * return slog.AnyValue(computeExpensiveValue(e.arg)) + * } + * ``` + * + * Then use a value of that type in log calls: + * + * ``` + * slog.Debug("frobbing", "value", expensive{arg}) + * ``` + * + * Now computeExpensiveValue will only be called when the line is enabled. + * + * The built-in handlers acquire a lock before calling [io.Writer.Write] + * to ensure that exactly one [Record] is written at a time in its entirety. + * Although each log record has a timestamp, + * the built-in handlers do not use that time to sort the written records. + * User-defined handlers are responsible for their own locking and sorting. + * + * # Writing a handler + * + * For a guide to writing a custom handler, see https://golang.org/s/slog-handler-guide. + */ +namespace slog { + // @ts-ignore + import loginternal = internal + /** + * A Logger records structured information about each call to its + * Log, Debug, Info, Warn, and Error methods. + * For each call, it creates a [Record] and passes it to a [Handler]. + * + * To create a new Logger, call [New] or a Logger method + * that begins "With". + */ + interface Logger { + } + interface Logger { + /** + * Handler returns l's Handler. + */ + handler(): Handler + } + interface Logger { + /** + * With returns a Logger that includes the given attributes + * in each output operation. Arguments are converted to + * attributes as if by [Logger.Log]. + */ + with(...args: any[]): (Logger) + } + interface Logger { + /** + * WithGroup returns a Logger that starts a group, if name is non-empty. + * The keys of all attributes added to the Logger will be qualified by the given + * name. (How that qualification happens depends on the [Handler.WithGroup] + * method of the Logger's Handler.) + * + * If name is empty, WithGroup returns the receiver. + */ + withGroup(name: string): (Logger) + } + interface Logger { + /** + * Enabled reports whether l emits log records at the given context and level. + */ + enabled(ctx: context.Context, level: Level): boolean + } + interface Logger { + /** + * Log emits a log record with the current time and the given level and message. + * The Record's Attrs consist of the Logger's attributes followed by + * the Attrs specified by args. + * + * The attribute arguments are processed as follows: + * ``` + * - If an argument is an Attr, it is used as is. + * - If an argument is a string and this is not the last argument, + * the following argument is treated as the value and the two are combined + * into an Attr. + * - Otherwise, the argument is treated as a value with key "!BADKEY". + * ``` + */ + log(ctx: context.Context, level: Level, msg: string, ...args: any[]): void + } + interface Logger { + /** + * LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs. + */ + logAttrs(ctx: context.Context, level: Level, msg: string, ...attrs: Attr[]): void + } + interface Logger { + /** + * Debug logs at [LevelDebug]. + */ + debug(msg: string, ...args: any[]): void + } + interface Logger { + /** + * DebugContext logs at [LevelDebug] with the given context. + */ + debugContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Info logs at [LevelInfo]. + */ + info(msg: string, ...args: any[]): void + } + interface Logger { + /** + * InfoContext logs at [LevelInfo] with the given context. + */ + infoContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Warn logs at [LevelWarn]. + */ + warn(msg: string, ...args: any[]): void + } + interface Logger { + /** + * WarnContext logs at [LevelWarn] with the given context. + */ + warnContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Error logs at [LevelError]. + */ + error(msg: string, ...args: any[]): void + } + interface Logger { + /** + * ErrorContext logs at [LevelError] with the given context. + */ + errorContext(ctx: context.Context, msg: string, ...args: any[]): void + } +} + +/** + * Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer + * object, creating another object (Reader or Writer) that also implements + * the interface but provides buffering and some help for textual I/O. + */ +namespace bufio { + /** + * ReadWriter stores pointers to a [Reader] and a [Writer]. + * It implements [io.ReadWriter]. + */ + type _sejIzvI = Reader&Writer + interface ReadWriter extends _sejIzvI { + } +} + /** * Package multipart implements MIME multipart parsing, as defined in RFC * 2046. @@ -16012,6 +16520,1212 @@ namespace multipart { } } +/** + * Package sql provides a generic interface around SQL (or SQL-like) + * databases. + * + * The sql package must be used in conjunction with a database driver. + * See https://golang.org/s/sqldrivers for a list of drivers. + * + * Drivers that do not support context cancellation will not return until + * after the query is completed. + * + * For usage examples, see the wiki page at + * https://golang.org/s/sqlwiki. + */ +namespace sql { + /** + * TxOptions holds the transaction options to be used in [DB.BeginTx]. + */ + interface TxOptions { + /** + * Isolation is the transaction isolation level. + * If zero, the driver or database's default level is used. + */ + isolation: IsolationLevel + readOnly: boolean + } + /** + * NullString represents a string that may be null. + * NullString implements the [Scanner] interface so + * it can be used as a scan destination: + * + * ``` + * var s NullString + * err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) + * ... + * if s.Valid { + * // use s.String + * } else { + * // NULL value + * } + * ``` + */ + interface NullString { + string: string + valid: boolean // Valid is true if String is not NULL + } + interface NullString { + /** + * Scan implements the [Scanner] interface. + */ + scan(value: any): void + } + interface NullString { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + /** + * DB is a database handle representing a pool of zero or more + * underlying connections. It's safe for concurrent use by multiple + * goroutines. + * + * The sql package creates and frees connections automatically; it + * also maintains a free pool of idle connections. If the database has + * a concept of per-connection state, such state can be reliably observed + * within a transaction ([Tx]) or connection ([Conn]). Once [DB.Begin] is called, the + * returned [Tx] is bound to a single connection. Once [Tx.Commit] or + * [Tx.Rollback] is called on the transaction, that transaction's + * connection is returned to [DB]'s idle connection pool. The pool size + * can be controlled with [DB.SetMaxIdleConns]. + */ + interface DB { + } + interface DB { + /** + * PingContext verifies a connection to the database is still alive, + * establishing a connection if necessary. + */ + pingContext(ctx: context.Context): void + } + interface DB { + /** + * Ping verifies a connection to the database is still alive, + * establishing a connection if necessary. + * + * Ping uses [context.Background] internally; to specify the context, use + * [DB.PingContext]. + */ + ping(): void + } + interface DB { + /** + * Close closes the database and prevents new queries from starting. + * Close then waits for all queries that have started processing on the server + * to finish. + * + * It is rare to Close a [DB], as the [DB] handle is meant to be + * long-lived and shared between many goroutines. + */ + close(): void + } + interface DB { + /** + * SetMaxIdleConns sets the maximum number of connections in the idle + * connection pool. + * + * If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, + * then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. + * + * If n <= 0, no idle connections are retained. + * + * The default max idle connections is currently 2. This may change in + * a future release. + */ + setMaxIdleConns(n: number): void + } + interface DB { + /** + * SetMaxOpenConns sets the maximum number of open connections to the database. + * + * If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than + * MaxIdleConns, then MaxIdleConns will be reduced to match the new + * MaxOpenConns limit. + * + * If n <= 0, then there is no limit on the number of open connections. + * The default is 0 (unlimited). + */ + setMaxOpenConns(n: number): void + } + interface DB { + /** + * SetConnMaxLifetime sets the maximum amount of time a connection may be reused. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's age. + */ + setConnMaxLifetime(d: time.Duration): void + } + interface DB { + /** + * SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's idle time. + */ + setConnMaxIdleTime(d: time.Duration): void + } + interface DB { + /** + * Stats returns database statistics. + */ + stats(): DBStats + } + interface DB { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface DB { + /** + * Prepare creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [DB.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface DB { + /** + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface DB { + /** + * Exec executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + * + * Exec uses [context.Background] internally; to specify the context, use + * [DB.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface DB { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * Query executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + * + * Query uses [context.Background] internally; to specify the context, use + * [DB.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface DB { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [DB.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + interface DB { + /** + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. + */ + beginTx(ctx: context.Context, opts: TxOptions): (Tx) + } + interface DB { + /** + * Begin starts a transaction. The default isolation level is dependent on + * the driver. + * + * Begin uses [context.Background] internally; to specify the context, use + * [DB.BeginTx]. + */ + begin(): (Tx) + } + interface DB { + /** + * Driver returns the database's underlying driver. + */ + driver(): any + } + interface DB { + /** + * Conn returns a single connection by either opening a new connection + * or returning an existing connection from the connection pool. Conn will + * block until either a connection is returned or ctx is canceled. + * Queries run on the same Conn will be run in the same database session. + * + * Every Conn must be returned to the database pool after use by + * calling [Conn.Close]. + */ + conn(ctx: context.Context): (Conn) + } + /** + * Tx is an in-progress database transaction. + * + * A transaction must end with a call to [Tx.Commit] or [Tx.Rollback]. + * + * After a call to [Tx.Commit] or [Tx.Rollback], all operations on the + * transaction fail with [ErrTxDone]. + * + * The statements prepared for a transaction by calling + * the transaction's [Tx.Prepare] or [Tx.Stmt] methods are closed + * by the call to [Tx.Commit] or [Tx.Rollback]. + */ + interface Tx { + } + interface Tx { + /** + * Commit commits the transaction. + */ + commit(): void + } + interface Tx { + /** + * Rollback aborts the transaction. + */ + rollback(): void + } + interface Tx { + /** + * PrepareContext creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * The provided context will be used for the preparation of the context, not + * for the execution of the returned statement. The returned statement + * will run in the transaction context. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface Tx { + /** + * Prepare creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [Tx.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface Tx { + /** + * StmtContext returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) + * ``` + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + */ + stmtContext(ctx: context.Context, stmt: Stmt): (Stmt) + } + interface Tx { + /** + * Stmt returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) + * ``` + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * Stmt uses [context.Background] internally; to specify the context, use + * [Tx.StmtContext]. + */ + stmt(stmt: Stmt): (Stmt) + } + interface Tx { + /** + * ExecContext executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Tx { + /** + * Exec executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Tx.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface Tx { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * Query executes a query that returns rows, typically a SELECT. + * + * Query uses [context.Background] internally; to specify the context, use + * [Tx.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Tx { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Tx.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + /** + * Stmt is a prepared statement. + * A Stmt is safe for concurrent use by multiple goroutines. + * + * If a Stmt is prepared on a [Tx] or [Conn], it will be bound to a single + * underlying connection forever. If the [Tx] or [Conn] closes, the Stmt will + * become unusable and all operations will return an error. + * If a Stmt is prepared on a [DB], it will remain usable for the lifetime of the + * [DB]. When the Stmt needs to execute on a new underlying connection, it will + * prepare itself on the new connection automatically. + */ + interface Stmt { + } + interface Stmt { + /** + * ExecContext executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + */ + execContext(ctx: context.Context, ...args: any[]): Result + } + interface Stmt { + /** + * Exec executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Stmt.ExecContext]. + */ + exec(...args: any[]): Result + } + interface Stmt { + /** + * QueryContext executes a prepared query statement with the given arguments + * and returns the query results as a [*Rows]. + */ + queryContext(ctx: context.Context, ...args: any[]): (Rows) + } + interface Stmt { + /** + * Query executes a prepared query statement with the given arguments + * and returns the query results as a *Rows. + * + * Query uses [context.Background] internally; to specify the context, use + * [Stmt.QueryContext]. + */ + query(...args: any[]): (Rows) + } + interface Stmt { + /** + * QueryRowContext executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, ...args: any[]): (Row) + } + interface Stmt { + /** + * QueryRow executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * Example usage: + * + * ``` + * var name string + * err := nameByUseridStmt.QueryRow(id).Scan(&name) + * ``` + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Stmt.QueryRowContext]. + */ + queryRow(...args: any[]): (Row) + } + interface Stmt { + /** + * Close closes the statement. + */ + close(): void + } + /** + * Rows is the result of a query. Its cursor starts before the first row + * of the result set. Use [Rows.Next] to advance from row to row. + */ + interface Rows { + } + interface Rows { + /** + * Next prepares the next result row for reading with the [Rows.Scan] method. It + * returns true on success, or false if there is no next result row or an error + * happened while preparing it. [Rows.Err] should be consulted to distinguish between + * the two cases. + * + * Every call to [Rows.Scan], even the first one, must be preceded by a call to [Rows.Next]. + */ + next(): boolean + } + interface Rows { + /** + * NextResultSet prepares the next result set for reading. It reports whether + * there is further result sets, or false if there is no further result set + * or if there is an error advancing to it. The [Rows.Err] method should be consulted + * to distinguish between the two cases. + * + * After calling NextResultSet, the [Rows.Next] method should always be called before + * scanning. If there are further result sets they may not have rows in the result + * set. + */ + nextResultSet(): boolean + } + interface Rows { + /** + * Err returns the error, if any, that was encountered during iteration. + * Err may be called after an explicit or implicit [Rows.Close]. + */ + err(): void + } + interface Rows { + /** + * Columns returns the column names. + * Columns returns an error if the rows are closed. + */ + columns(): Array + } + interface Rows { + /** + * ColumnTypes returns column information such as column type, length, + * and nullable. Some information may not be available from some drivers. + */ + columnTypes(): Array<(ColumnType | undefined)> + } + interface Rows { + /** + * Scan copies the columns in the current row into the values pointed + * at by dest. The number of values in dest must be the same as the + * number of columns in [Rows]. + * + * Scan converts columns read from the database into the following + * common Go types and special types provided by the sql package: + * + * ``` + * *string + * *[]byte + * *int, *int8, *int16, *int32, *int64 + * *uint, *uint8, *uint16, *uint32, *uint64 + * *bool + * *float32, *float64 + * *interface{} + * *RawBytes + * *Rows (cursor value) + * any type implementing Scanner (see Scanner docs) + * ``` + * + * In the most simple case, if the type of the value from the source + * column is an integer, bool or string type T and dest is of type *T, + * Scan simply assigns the value through the pointer. + * + * Scan also converts between string and numeric types, as long as no + * information would be lost. While Scan stringifies all numbers + * scanned from numeric database columns into *string, scans into + * numeric types are checked for overflow. For example, a float64 with + * value 300 or a string with value "300" can scan into a uint16, but + * not into a uint8, though float64(255) or "255" can scan into a + * uint8. One exception is that scans of some float64 numbers to + * strings may lose information when stringifying. In general, scan + * floating point columns into *float64. + * + * If a dest argument has type *[]byte, Scan saves in that argument a + * copy of the corresponding data. The copy is owned by the caller and + * can be modified and held indefinitely. The copy can be avoided by + * using an argument of type [*RawBytes] instead; see the documentation + * for [RawBytes] for restrictions on its use. + * + * If an argument has type *interface{}, Scan copies the value + * provided by the underlying driver without conversion. When scanning + * from a source value of type []byte to *interface{}, a copy of the + * slice is made and the caller owns the result. + * + * Source values of type [time.Time] may be scanned into values of type + * *time.Time, *interface{}, *string, or *[]byte. When converting to + * the latter two, [time.RFC3339Nano] is used. + * + * Source values of type bool may be scanned into types *bool, + * *interface{}, *string, *[]byte, or [*RawBytes]. + * + * For scanning into *bool, the source may be true, false, 1, 0, or + * string inputs parseable by [strconv.ParseBool]. + * + * Scan can also convert a cursor returned from a query, such as + * "select cursor(select * from my_table) from dual", into a + * [*Rows] value that can itself be scanned from. The parent + * select query will close any cursor [*Rows] if the parent [*Rows] is closed. + * + * If any of the first arguments implementing [Scanner] returns an error, + * that error will be wrapped in the returned error. + */ + scan(...dest: any[]): void + } + interface Rows { + /** + * Close closes the [Rows], preventing further enumeration. If [Rows.Next] is called + * and returns false and there are no further result sets, + * the [Rows] are closed automatically and it will suffice to check the + * result of [Rows.Err]. Close is idempotent and does not affect the result of [Rows.Err]. + */ + close(): void + } + /** + * A Result summarizes an executed SQL command. + */ + interface Result { + [key:string]: any; + /** + * LastInsertId returns the integer generated by the database + * in response to a command. Typically this will be from an + * "auto increment" column when inserting a new row. Not all + * databases support this feature, and the syntax of such + * statements varies. + */ + lastInsertId(): number + /** + * RowsAffected returns the number of rows affected by an + * update, insert, or delete. Not every database or database + * driver may support this. + */ + rowsAffected(): number + } +} + +/** + * Package syntax parses regular expressions into parse trees and compiles + * parse trees into programs. Most clients of regular expressions will use the + * facilities of package [regexp] (such as [regexp.Compile] and [regexp.Match]) instead of this package. + * + * # Syntax + * + * The regular expression syntax understood by this package when parsing with the [Perl] flag is as follows. + * Parts of the syntax can be disabled by passing alternate flags to [Parse]. + * + * Single characters: + * + * ``` + * . any character, possibly including newline (flag s=true) + * [xyz] character class + * [^xyz] negated character class + * \d Perl character class + * \D negated Perl character class + * [[:alpha:]] ASCII character class + * [[:^alpha:]] negated ASCII character class + * \pN Unicode character class (one-letter name) + * \p{Greek} Unicode character class + * \PN negated Unicode character class (one-letter name) + * \P{Greek} negated Unicode character class + * ``` + * + * Composites: + * + * ``` + * xy x followed by y + * x|y x or y (prefer x) + * ``` + * + * Repetitions: + * + * ``` + * x* zero or more x, prefer more + * x+ one or more x, prefer more + * x? zero or one x, prefer one + * x{n,m} n or n+1 or ... or m x, prefer more + * x{n,} n or more x, prefer more + * x{n} exactly n x + * x*? zero or more x, prefer fewer + * x+? one or more x, prefer fewer + * x?? zero or one x, prefer zero + * x{n,m}? n or n+1 or ... or m x, prefer fewer + * x{n,}? n or more x, prefer fewer + * x{n}? exactly n x + * ``` + * + * Implementation restriction: The counting forms x{n,m}, x{n,}, and x{n} + * reject forms that create a minimum or maximum repetition count above 1000. + * Unlimited repetitions are not subject to this restriction. + * + * Grouping: + * + * ``` + * (re) numbered capturing group (submatch) + * (?Pre) named & numbered capturing group (submatch) + * (?re) named & numbered capturing group (submatch) + * (?:re) non-capturing group + * (?flags) set flags within current group; non-capturing + * (?flags:re) set flags during re; non-capturing + * + * Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are: + * + * i case-insensitive (default false) + * m multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false) + * s let . match \n (default false) + * U ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false) + * ``` + * + * Empty strings: + * + * ``` + * ^ at beginning of text or line (flag m=true) + * $ at end of text (like \z not \Z) or line (flag m=true) + * \A at beginning of text + * \b at ASCII word boundary (\w on one side and \W, \A, or \z on the other) + * \B not at ASCII word boundary + * \z at end of text + * ``` + * + * Escape sequences: + * + * ``` + * \a bell (== \007) + * \f form feed (== \014) + * \t horizontal tab (== \011) + * \n newline (== \012) + * \r carriage return (== \015) + * \v vertical tab character (== \013) + * \* literal *, for any punctuation character * + * \123 octal character code (up to three digits) + * \x7F hex character code (exactly two digits) + * \x{10FFFF} hex character code + * \Q...\E literal text ... even if ... has punctuation + * ``` + * + * Character class elements: + * + * ``` + * x single character + * A-Z character range (inclusive) + * \d Perl character class + * [:foo:] ASCII character class foo + * \p{Foo} Unicode character class Foo + * \pF Unicode character class F (one-letter name) + * ``` + * + * Named character classes as character class elements: + * + * ``` + * [\d] digits (== \d) + * [^\d] not digits (== \D) + * [\D] not digits (== \D) + * [^\D] not not digits (== \d) + * [[:name:]] named ASCII class inside character class (== [:name:]) + * [^[:name:]] named ASCII class inside negated character class (== [:^name:]) + * [\p{Name}] named Unicode property inside character class (== \p{Name}) + * [^\p{Name}] named Unicode property inside negated character class (== \P{Name}) + * ``` + * + * Perl character classes (all ASCII-only): + * + * ``` + * \d digits (== [0-9]) + * \D not digits (== [^0-9]) + * \s whitespace (== [\t\n\f\r ]) + * \S not whitespace (== [^\t\n\f\r ]) + * \w word characters (== [0-9A-Za-z_]) + * \W not word characters (== [^0-9A-Za-z_]) + * ``` + * + * ASCII character classes: + * + * ``` + * [[:alnum:]] alphanumeric (== [0-9A-Za-z]) + * [[:alpha:]] alphabetic (== [A-Za-z]) + * [[:ascii:]] ASCII (== [\x00-\x7F]) + * [[:blank:]] blank (== [\t ]) + * [[:cntrl:]] control (== [\x00-\x1F\x7F]) + * [[:digit:]] digits (== [0-9]) + * [[:graph:]] graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]) + * [[:lower:]] lower case (== [a-z]) + * [[:print:]] printable (== [ -~] == [ [:graph:]]) + * [[:punct:]] punctuation (== [!-/:-@[-`{-~]) + * [[:space:]] whitespace (== [\t\n\v\f\r ]) + * [[:upper:]] upper case (== [A-Z]) + * [[:word:]] word characters (== [0-9A-Za-z_]) + * [[:xdigit:]] hex digit (== [0-9A-Fa-f]) + * ``` + * + * Unicode character classes are those in [unicode.Categories] and [unicode.Scripts]. + */ +namespace syntax { + /** + * Flags control the behavior of the parser and record information about regexp context. + */ + interface Flags extends Number{} +} + +namespace store { + /** + * Store defines a concurrent safe in memory key-value data store. + */ + interface Store { + } + interface Store { + /** + * Reset clears the store and replaces the store data with a + * shallow copy of the provided newData. + */ + reset(newData: _TygojaDict): void + } + interface Store { + /** + * Length returns the current number of elements in the store. + */ + length(): number + } + interface Store { + /** + * RemoveAll removes all the existing store entries. + */ + removeAll(): void + } + interface Store { + /** + * Remove removes a single entry from the store. + * + * Remove does nothing if key doesn't exist in the store. + */ + remove(key: K): void + } + interface Store { + /** + * Has checks if element with the specified key exist or not. + */ + has(key: K): boolean + } + interface Store { + /** + * Get returns a single element value from the store. + * + * If key is not set, the zero T value is returned. + */ + get(key: K): T + } + interface Store { + /** + * GetOk is similar to Get but returns also a boolean indicating whether the key exists or not. + */ + getOk(key: K): [T, boolean] + } + interface Store { + /** + * GetAll returns a shallow copy of the current store data. + */ + getAll(): _TygojaDict + } + interface Store { + /** + * Values returns a slice with all of the current store values. + */ + values(): Array + } + interface Store { + /** + * Set sets (or overwrite if already exists) a new value for key. + */ + set(key: K, value: T): void + } + interface Store { + /** + * SetFunc sets (or overwrite if already exists) a new value resolved + * from the function callback for the provided key. + * + * The function callback receives as argument the old store element value (if exists). + * If there is no old store element, the argument will be the T zero value. + * + * Example: + * + * ``` + * s := store.New[string, int](nil) + * s.SetFunc("count", func(old int) int { + * return old + 1 + * }) + * ``` + */ + setFunc(key: K, fn: (old: T) => T): void + } + interface Store { + /** + * GetOrSet retrieves a single existing value for the provided key + * or stores a new one if it doesn't exist. + */ + getOrSet(key: K, setFunc: () => T): T + } + interface Store { + /** + * SetIfLessThanLimit sets (or overwrite if already exist) a new value for key. + * + * This method is similar to Set() but **it will skip adding new elements** + * to the store if the store length has reached the specified limit. + * false is returned if maxAllowedElements limit is reached. + */ + setIfLessThanLimit(key: K, value: T, maxAllowedElements: number): boolean + } + interface Store { + /** + * UnmarshalJSON implements [json.Unmarshaler] and imports the + * provided JSON data into the store. + * + * The store entries that match with the ones from the data will be overwritten with the new value. + */ + unmarshalJSON(data: string|Array): void + } + interface Store { + /** + * MarshalJSON implements [json.Marshaler] and export the current + * store data into valid JSON. + */ + marshalJSON(): string|Array + } +} + +/** + * Package types implements some commonly used db serializable types + * like datetime, json, etc. + */ +namespace types { + /** + * DateTime represents a [time.Time] instance in UTC that is wrapped + * and serialized using the app default date layout. + */ + interface DateTime { + } + interface DateTime { + /** + * Time returns the internal [time.Time] instance. + */ + time(): time.Time + } + interface DateTime { + /** + * Add returns a new DateTime based on the current DateTime + the specified duration. + */ + add(duration: time.Duration): DateTime + } + interface DateTime { + /** + * Sub returns a [time.Duration] by subtracting the specified DateTime from the current one. + * + * If the result exceeds the maximum (or minimum) value that can be stored in a [time.Duration], + * the maximum (or minimum) duration will be returned. + */ + sub(u: DateTime): time.Duration + } + interface DateTime { + /** + * AddDate returns a new DateTime based on the current one + duration. + * + * It follows the same rules as [time.AddDate]. + */ + addDate(years: number, months: number, days: number): DateTime + } + interface DateTime { + /** + * After reports whether the current DateTime instance is after u. + */ + after(u: DateTime): boolean + } + interface DateTime { + /** + * Before reports whether the current DateTime instance is before u. + */ + before(u: DateTime): boolean + } + interface DateTime { + /** + * Compare compares the current DateTime instance with u. + * If the current instance is before u, it returns -1. + * If the current instance is after u, it returns +1. + * If they're the same, it returns 0. + */ + compare(u: DateTime): number + } + interface DateTime { + /** + * Equal reports whether the current DateTime and u represent the same time instant. + * Two DateTime can be equal even if they are in different locations. + * For example, 6:00 +0200 and 4:00 UTC are Equal. + */ + equal(u: DateTime): boolean + } + interface DateTime { + /** + * Unix returns the current DateTime as a Unix time, aka. + * the number of seconds elapsed since January 1, 1970 UTC. + */ + unix(): number + } + interface DateTime { + /** + * IsZero checks whether the current DateTime instance has zero time value. + */ + isZero(): boolean + } + interface DateTime { + /** + * String serializes the current DateTime instance into a formatted + * UTC date string. + * + * The zero value is serialized to an empty string. + */ + string(): string + } + interface DateTime { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface DateTime { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface DateTime { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface DateTime { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current DateTime instance. + */ + scan(value: any): void + } + /** + * GeoPoint defines a struct for storing geo coordinates as serialized json object + * (e.g. {lon:0,lat:0}). + * + * Note: using object notation and not a plain array to avoid the confusion + * as there doesn't seem to be a fixed standard for the coordinates order. + */ + interface GeoPoint { + lon: number + lat: number + } + interface GeoPoint { + /** + * String returns the string representation of the current GeoPoint instance. + */ + string(): string + } + interface GeoPoint { + /** + * AsMap implements [core.mapExtractor] and returns a value suitable + * to be used in an API rule expression. + */ + asMap(): _TygojaDict + } + interface GeoPoint { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface GeoPoint { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current GeoPoint instance. + * + * The value argument could be nil (no-op), another GeoPoint instance, + * map or serialized json object with lat-lon props. + */ + scan(value: any): void + } + /** + * JSONArray defines a slice that is safe for json and db read/write. + */ + interface JSONArray extends Array{} + /** + * JSONMap defines a map that is safe for json and db read/write. + */ + interface JSONMap extends _TygojaDict{} + /** + * JSONRaw defines a json value type that is safe for db read/write. + */ + interface JSONRaw extends Array{} + interface JSONRaw { + /** + * String returns the current JSONRaw instance as a json encoded string. + */ + string(): string + } + interface JSONRaw { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONRaw { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface JSONRaw { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONRaw { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONRaw instance. + */ + scan(value: any): void + } +} + +namespace search { + /** + * Result defines the returned search result structure. + */ + interface Result { + items: any + page: number + perPage: number + totalItems: number + totalPages: number + } + /** + * ResolverResult defines a single FieldResolver.Resolve() successfully parsed result. + */ + interface ResolverResult { + /** + * Identifier is the plain SQL identifier/column that will be used + * in the final db expression as left or right operand. + */ + identifier: string + /** + * NoCoalesce instructs to not use COALESCE or NULL fallbacks + * when building the identifier expression. + */ + noCoalesce: boolean + /** + * Params is a map with db placeholder->value pairs that will be added + * to the query when building both resolved operands/sides in a single expression. + */ + params: dbx.Params + /** + * MultiMatchSubQuery is an optional sub query expression that will be added + * in addition to the combined ResolverResult expression during build. + */ + multiMatchSubQuery: dbx.Expression + /** + * AfterBuild is an optional function that will be called after building + * and combining the result of both resolved operands/sides in a single expression. + */ + afterBuild: (expr: dbx.Expression) => dbx.Expression + } +} + /** * Package http provides HTTP client and server implementations. * @@ -17000,681 +18714,6 @@ namespace http { } } -/** - * Package sql provides a generic interface around SQL (or SQL-like) - * databases. - * - * The sql package must be used in conjunction with a database driver. - * See https://golang.org/s/sqldrivers for a list of drivers. - * - * Drivers that do not support context cancellation will not return until - * after the query is completed. - * - * For usage examples, see the wiki page at - * https://golang.org/s/sqlwiki. - */ -namespace sql { - /** - * TxOptions holds the transaction options to be used in [DB.BeginTx]. - */ - interface TxOptions { - /** - * Isolation is the transaction isolation level. - * If zero, the driver or database's default level is used. - */ - isolation: IsolationLevel - readOnly: boolean - } - /** - * NullString represents a string that may be null. - * NullString implements the [Scanner] interface so - * it can be used as a scan destination: - * - * ``` - * var s NullString - * err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) - * ... - * if s.Valid { - * // use s.String - * } else { - * // NULL value - * } - * ``` - */ - interface NullString { - string: string - valid: boolean // Valid is true if String is not NULL - } - interface NullString { - /** - * Scan implements the [Scanner] interface. - */ - scan(value: any): void - } - interface NullString { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - /** - * DB is a database handle representing a pool of zero or more - * underlying connections. It's safe for concurrent use by multiple - * goroutines. - * - * The sql package creates and frees connections automatically; it - * also maintains a free pool of idle connections. If the database has - * a concept of per-connection state, such state can be reliably observed - * within a transaction ([Tx]) or connection ([Conn]). Once [DB.Begin] is called, the - * returned [Tx] is bound to a single connection. Once [Tx.Commit] or - * [Tx.Rollback] is called on the transaction, that transaction's - * connection is returned to [DB]'s idle connection pool. The pool size - * can be controlled with [DB.SetMaxIdleConns]. - */ - interface DB { - } - interface DB { - /** - * PingContext verifies a connection to the database is still alive, - * establishing a connection if necessary. - */ - pingContext(ctx: context.Context): void - } - interface DB { - /** - * Ping verifies a connection to the database is still alive, - * establishing a connection if necessary. - * - * Ping uses [context.Background] internally; to specify the context, use - * [DB.PingContext]. - */ - ping(): void - } - interface DB { - /** - * Close closes the database and prevents new queries from starting. - * Close then waits for all queries that have started processing on the server - * to finish. - * - * It is rare to Close a [DB], as the [DB] handle is meant to be - * long-lived and shared between many goroutines. - */ - close(): void - } - interface DB { - /** - * SetMaxIdleConns sets the maximum number of connections in the idle - * connection pool. - * - * If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, - * then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. - * - * If n <= 0, no idle connections are retained. - * - * The default max idle connections is currently 2. This may change in - * a future release. - */ - setMaxIdleConns(n: number): void - } - interface DB { - /** - * SetMaxOpenConns sets the maximum number of open connections to the database. - * - * If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than - * MaxIdleConns, then MaxIdleConns will be reduced to match the new - * MaxOpenConns limit. - * - * If n <= 0, then there is no limit on the number of open connections. - * The default is 0 (unlimited). - */ - setMaxOpenConns(n: number): void - } - interface DB { - /** - * SetConnMaxLifetime sets the maximum amount of time a connection may be reused. - * - * Expired connections may be closed lazily before reuse. - * - * If d <= 0, connections are not closed due to a connection's age. - */ - setConnMaxLifetime(d: time.Duration): void - } - interface DB { - /** - * SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. - * - * Expired connections may be closed lazily before reuse. - * - * If d <= 0, connections are not closed due to a connection's idle time. - */ - setConnMaxIdleTime(d: time.Duration): void - } - interface DB { - /** - * Stats returns database statistics. - */ - stats(): DBStats - } - interface DB { - /** - * PrepareContext creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface DB { - /** - * Prepare creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * Prepare uses [context.Background] internally; to specify the context, use - * [DB.PrepareContext]. - */ - prepare(query: string): (Stmt) - } - interface DB { - /** - * ExecContext executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface DB { - /** - * Exec executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - * - * Exec uses [context.Background] internally; to specify the context, use - * [DB.ExecContext]. - */ - exec(query: string, ...args: any[]): Result - } - interface DB { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface DB { - /** - * Query executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - * - * Query uses [context.Background] internally; to specify the context, use - * [DB.QueryContext]. - */ - query(query: string, ...args: any[]): (Rows) - } - interface DB { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface DB { - /** - * QueryRow executes a query that is expected to return at most one row. - * QueryRow always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, [*Row.Scan] scans the first selected row and discards - * the rest. - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [DB.QueryRowContext]. - */ - queryRow(query: string, ...args: any[]): (Row) - } - interface DB { - /** - * BeginTx starts a transaction. - * - * The provided context is used until the transaction is committed or rolled back. - * If the context is canceled, the sql package will roll back - * the transaction. [Tx.Commit] will return an error if the context provided to - * BeginTx is canceled. - * - * The provided [TxOptions] is optional and may be nil if defaults should be used. - * If a non-default isolation level is used that the driver doesn't support, - * an error will be returned. - */ - beginTx(ctx: context.Context, opts: TxOptions): (Tx) - } - interface DB { - /** - * Begin starts a transaction. The default isolation level is dependent on - * the driver. - * - * Begin uses [context.Background] internally; to specify the context, use - * [DB.BeginTx]. - */ - begin(): (Tx) - } - interface DB { - /** - * Driver returns the database's underlying driver. - */ - driver(): any - } - interface DB { - /** - * Conn returns a single connection by either opening a new connection - * or returning an existing connection from the connection pool. Conn will - * block until either a connection is returned or ctx is canceled. - * Queries run on the same Conn will be run in the same database session. - * - * Every Conn must be returned to the database pool after use by - * calling [Conn.Close]. - */ - conn(ctx: context.Context): (Conn) - } - /** - * Tx is an in-progress database transaction. - * - * A transaction must end with a call to [Tx.Commit] or [Tx.Rollback]. - * - * After a call to [Tx.Commit] or [Tx.Rollback], all operations on the - * transaction fail with [ErrTxDone]. - * - * The statements prepared for a transaction by calling - * the transaction's [Tx.Prepare] or [Tx.Stmt] methods are closed - * by the call to [Tx.Commit] or [Tx.Rollback]. - */ - interface Tx { - } - interface Tx { - /** - * Commit commits the transaction. - */ - commit(): void - } - interface Tx { - /** - * Rollback aborts the transaction. - */ - rollback(): void - } - interface Tx { - /** - * PrepareContext creates a prepared statement for use within a transaction. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * To use an existing prepared statement on this transaction, see [Tx.Stmt]. - * - * The provided context will be used for the preparation of the context, not - * for the execution of the returned statement. The returned statement - * will run in the transaction context. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface Tx { - /** - * Prepare creates a prepared statement for use within a transaction. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * To use an existing prepared statement on this transaction, see [Tx.Stmt]. - * - * Prepare uses [context.Background] internally; to specify the context, use - * [Tx.PrepareContext]. - */ - prepare(query: string): (Stmt) - } - interface Tx { - /** - * StmtContext returns a transaction-specific prepared statement from - * an existing statement. - * - * Example: - * - * ``` - * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") - * ... - * tx, err := db.Begin() - * ... - * res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) - * ``` - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - */ - stmtContext(ctx: context.Context, stmt: Stmt): (Stmt) - } - interface Tx { - /** - * Stmt returns a transaction-specific prepared statement from - * an existing statement. - * - * Example: - * - * ``` - * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") - * ... - * tx, err := db.Begin() - * ... - * res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) - * ``` - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * Stmt uses [context.Background] internally; to specify the context, use - * [Tx.StmtContext]. - */ - stmt(stmt: Stmt): (Stmt) - } - interface Tx { - /** - * ExecContext executes a query that doesn't return rows. - * For example: an INSERT and UPDATE. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface Tx { - /** - * Exec executes a query that doesn't return rows. - * For example: an INSERT and UPDATE. - * - * Exec uses [context.Background] internally; to specify the context, use - * [Tx.ExecContext]. - */ - exec(query: string, ...args: any[]): Result - } - interface Tx { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface Tx { - /** - * Query executes a query that returns rows, typically a SELECT. - * - * Query uses [context.Background] internally; to specify the context, use - * [Tx.QueryContext]. - */ - query(query: string, ...args: any[]): (Rows) - } - interface Tx { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface Tx { - /** - * QueryRow executes a query that is expected to return at most one row. - * QueryRow always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [Tx.QueryRowContext]. - */ - queryRow(query: string, ...args: any[]): (Row) - } - /** - * Stmt is a prepared statement. - * A Stmt is safe for concurrent use by multiple goroutines. - * - * If a Stmt is prepared on a [Tx] or [Conn], it will be bound to a single - * underlying connection forever. If the [Tx] or [Conn] closes, the Stmt will - * become unusable and all operations will return an error. - * If a Stmt is prepared on a [DB], it will remain usable for the lifetime of the - * [DB]. When the Stmt needs to execute on a new underlying connection, it will - * prepare itself on the new connection automatically. - */ - interface Stmt { - } - interface Stmt { - /** - * ExecContext executes a prepared statement with the given arguments and - * returns a [Result] summarizing the effect of the statement. - */ - execContext(ctx: context.Context, ...args: any[]): Result - } - interface Stmt { - /** - * Exec executes a prepared statement with the given arguments and - * returns a [Result] summarizing the effect of the statement. - * - * Exec uses [context.Background] internally; to specify the context, use - * [Stmt.ExecContext]. - */ - exec(...args: any[]): Result - } - interface Stmt { - /** - * QueryContext executes a prepared query statement with the given arguments - * and returns the query results as a [*Rows]. - */ - queryContext(ctx: context.Context, ...args: any[]): (Rows) - } - interface Stmt { - /** - * Query executes a prepared query statement with the given arguments - * and returns the query results as a *Rows. - * - * Query uses [context.Background] internally; to specify the context, use - * [Stmt.QueryContext]. - */ - query(...args: any[]): (Rows) - } - interface Stmt { - /** - * QueryRowContext executes a prepared query statement with the given arguments. - * If an error occurs during the execution of the statement, that error will - * be returned by a call to Scan on the returned [*Row], which is always non-nil. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, ...args: any[]): (Row) - } - interface Stmt { - /** - * QueryRow executes a prepared query statement with the given arguments. - * If an error occurs during the execution of the statement, that error will - * be returned by a call to Scan on the returned [*Row], which is always non-nil. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - * - * Example usage: - * - * ``` - * var name string - * err := nameByUseridStmt.QueryRow(id).Scan(&name) - * ``` - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [Stmt.QueryRowContext]. - */ - queryRow(...args: any[]): (Row) - } - interface Stmt { - /** - * Close closes the statement. - */ - close(): void - } - /** - * Rows is the result of a query. Its cursor starts before the first row - * of the result set. Use [Rows.Next] to advance from row to row. - */ - interface Rows { - } - interface Rows { - /** - * Next prepares the next result row for reading with the [Rows.Scan] method. It - * returns true on success, or false if there is no next result row or an error - * happened while preparing it. [Rows.Err] should be consulted to distinguish between - * the two cases. - * - * Every call to [Rows.Scan], even the first one, must be preceded by a call to [Rows.Next]. - */ - next(): boolean - } - interface Rows { - /** - * NextResultSet prepares the next result set for reading. It reports whether - * there is further result sets, or false if there is no further result set - * or if there is an error advancing to it. The [Rows.Err] method should be consulted - * to distinguish between the two cases. - * - * After calling NextResultSet, the [Rows.Next] method should always be called before - * scanning. If there are further result sets they may not have rows in the result - * set. - */ - nextResultSet(): boolean - } - interface Rows { - /** - * Err returns the error, if any, that was encountered during iteration. - * Err may be called after an explicit or implicit [Rows.Close]. - */ - err(): void - } - interface Rows { - /** - * Columns returns the column names. - * Columns returns an error if the rows are closed. - */ - columns(): Array - } - interface Rows { - /** - * ColumnTypes returns column information such as column type, length, - * and nullable. Some information may not be available from some drivers. - */ - columnTypes(): Array<(ColumnType | undefined)> - } - interface Rows { - /** - * Scan copies the columns in the current row into the values pointed - * at by dest. The number of values in dest must be the same as the - * number of columns in [Rows]. - * - * Scan converts columns read from the database into the following - * common Go types and special types provided by the sql package: - * - * ``` - * *string - * *[]byte - * *int, *int8, *int16, *int32, *int64 - * *uint, *uint8, *uint16, *uint32, *uint64 - * *bool - * *float32, *float64 - * *interface{} - * *RawBytes - * *Rows (cursor value) - * any type implementing Scanner (see Scanner docs) - * ``` - * - * In the most simple case, if the type of the value from the source - * column is an integer, bool or string type T and dest is of type *T, - * Scan simply assigns the value through the pointer. - * - * Scan also converts between string and numeric types, as long as no - * information would be lost. While Scan stringifies all numbers - * scanned from numeric database columns into *string, scans into - * numeric types are checked for overflow. For example, a float64 with - * value 300 or a string with value "300" can scan into a uint16, but - * not into a uint8, though float64(255) or "255" can scan into a - * uint8. One exception is that scans of some float64 numbers to - * strings may lose information when stringifying. In general, scan - * floating point columns into *float64. - * - * If a dest argument has type *[]byte, Scan saves in that argument a - * copy of the corresponding data. The copy is owned by the caller and - * can be modified and held indefinitely. The copy can be avoided by - * using an argument of type [*RawBytes] instead; see the documentation - * for [RawBytes] for restrictions on its use. - * - * If an argument has type *interface{}, Scan copies the value - * provided by the underlying driver without conversion. When scanning - * from a source value of type []byte to *interface{}, a copy of the - * slice is made and the caller owns the result. - * - * Source values of type [time.Time] may be scanned into values of type - * *time.Time, *interface{}, *string, or *[]byte. When converting to - * the latter two, [time.RFC3339Nano] is used. - * - * Source values of type bool may be scanned into types *bool, - * *interface{}, *string, *[]byte, or [*RawBytes]. - * - * For scanning into *bool, the source may be true, false, 1, 0, or - * string inputs parseable by [strconv.ParseBool]. - * - * Scan can also convert a cursor returned from a query, such as - * "select cursor(select * from my_table) from dual", into a - * [*Rows] value that can itself be scanned from. The parent - * select query will close any cursor [*Rows] if the parent [*Rows] is closed. - * - * If any of the first arguments implementing [Scanner] returns an error, - * that error will be wrapped in the returned error. - */ - scan(...dest: any[]): void - } - interface Rows { - /** - * Close closes the [Rows], preventing further enumeration. If [Rows.Next] is called - * and returns false and there are no further result sets, - * the [Rows] are closed automatically and it will suffice to check the - * result of [Rows.Err]. Close is idempotent and does not affect the result of [Rows.Err]. - */ - close(): void - } - /** - * A Result summarizes an executed SQL command. - */ - interface Result { - [key:string]: any; - /** - * LastInsertId returns the integer generated by the database - * in response to a command. Typically this will be from an - * "auto increment" column when inserting a new row. Not all - * databases support this feature, and the syntax of such - * statements varies. - */ - lastInsertId(): number - /** - * RowsAffected returns the number of rows affected by an - * update, insert, or delete. Not every database or database - * driver may support this. - */ - rowsAffected(): number - } -} - /** * Package blob defines a lightweight abstration for interacting with * various storage services (local filesystem, S3, etc.). @@ -17835,342 +18874,6 @@ namespace blob { } } -/** - * Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html - * - * See README.md for more info. - */ -namespace jwt { - /** - * MapClaims is a claims type that uses the map[string]interface{} for JSON - * decoding. This is the default claims type if you don't supply one - */ - interface MapClaims extends _TygojaDict{} - interface MapClaims { - /** - * GetExpirationTime implements the Claims interface. - */ - getExpirationTime(): (NumericDate) - } - interface MapClaims { - /** - * GetNotBefore implements the Claims interface. - */ - getNotBefore(): (NumericDate) - } - interface MapClaims { - /** - * GetIssuedAt implements the Claims interface. - */ - getIssuedAt(): (NumericDate) - } - interface MapClaims { - /** - * GetAudience implements the Claims interface. - */ - getAudience(): ClaimStrings - } - interface MapClaims { - /** - * GetIssuer implements the Claims interface. - */ - getIssuer(): string - } - interface MapClaims { - /** - * GetSubject implements the Claims interface. - */ - getSubject(): string - } -} - -/** - * Package syntax parses regular expressions into parse trees and compiles - * parse trees into programs. Most clients of regular expressions will use the - * facilities of package [regexp] (such as [regexp.Compile] and [regexp.Match]) instead of this package. - * - * # Syntax - * - * The regular expression syntax understood by this package when parsing with the [Perl] flag is as follows. - * Parts of the syntax can be disabled by passing alternate flags to [Parse]. - * - * Single characters: - * - * ``` - * . any character, possibly including newline (flag s=true) - * [xyz] character class - * [^xyz] negated character class - * \d Perl character class - * \D negated Perl character class - * [[:alpha:]] ASCII character class - * [[:^alpha:]] negated ASCII character class - * \pN Unicode character class (one-letter name) - * \p{Greek} Unicode character class - * \PN negated Unicode character class (one-letter name) - * \P{Greek} negated Unicode character class - * ``` - * - * Composites: - * - * ``` - * xy x followed by y - * x|y x or y (prefer x) - * ``` - * - * Repetitions: - * - * ``` - * x* zero or more x, prefer more - * x+ one or more x, prefer more - * x? zero or one x, prefer one - * x{n,m} n or n+1 or ... or m x, prefer more - * x{n,} n or more x, prefer more - * x{n} exactly n x - * x*? zero or more x, prefer fewer - * x+? one or more x, prefer fewer - * x?? zero or one x, prefer zero - * x{n,m}? n or n+1 or ... or m x, prefer fewer - * x{n,}? n or more x, prefer fewer - * x{n}? exactly n x - * ``` - * - * Implementation restriction: The counting forms x{n,m}, x{n,}, and x{n} - * reject forms that create a minimum or maximum repetition count above 1000. - * Unlimited repetitions are not subject to this restriction. - * - * Grouping: - * - * ``` - * (re) numbered capturing group (submatch) - * (?Pre) named & numbered capturing group (submatch) - * (?re) named & numbered capturing group (submatch) - * (?:re) non-capturing group - * (?flags) set flags within current group; non-capturing - * (?flags:re) set flags during re; non-capturing - * - * Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are: - * - * i case-insensitive (default false) - * m multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false) - * s let . match \n (default false) - * U ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false) - * ``` - * - * Empty strings: - * - * ``` - * ^ at beginning of text or line (flag m=true) - * $ at end of text (like \z not \Z) or line (flag m=true) - * \A at beginning of text - * \b at ASCII word boundary (\w on one side and \W, \A, or \z on the other) - * \B not at ASCII word boundary - * \z at end of text - * ``` - * - * Escape sequences: - * - * ``` - * \a bell (== \007) - * \f form feed (== \014) - * \t horizontal tab (== \011) - * \n newline (== \012) - * \r carriage return (== \015) - * \v vertical tab character (== \013) - * \* literal *, for any punctuation character * - * \123 octal character code (up to three digits) - * \x7F hex character code (exactly two digits) - * \x{10FFFF} hex character code - * \Q...\E literal text ... even if ... has punctuation - * ``` - * - * Character class elements: - * - * ``` - * x single character - * A-Z character range (inclusive) - * \d Perl character class - * [:foo:] ASCII character class foo - * \p{Foo} Unicode character class Foo - * \pF Unicode character class F (one-letter name) - * ``` - * - * Named character classes as character class elements: - * - * ``` - * [\d] digits (== \d) - * [^\d] not digits (== \D) - * [\D] not digits (== \D) - * [^\D] not not digits (== \d) - * [[:name:]] named ASCII class inside character class (== [:name:]) - * [^[:name:]] named ASCII class inside negated character class (== [:^name:]) - * [\p{Name}] named Unicode property inside character class (== \p{Name}) - * [^\p{Name}] named Unicode property inside negated character class (== \P{Name}) - * ``` - * - * Perl character classes (all ASCII-only): - * - * ``` - * \d digits (== [0-9]) - * \D not digits (== [^0-9]) - * \s whitespace (== [\t\n\f\r ]) - * \S not whitespace (== [^\t\n\f\r ]) - * \w word characters (== [0-9A-Za-z_]) - * \W not word characters (== [^0-9A-Za-z_]) - * ``` - * - * ASCII character classes: - * - * ``` - * [[:alnum:]] alphanumeric (== [0-9A-Za-z]) - * [[:alpha:]] alphabetic (== [A-Za-z]) - * [[:ascii:]] ASCII (== [\x00-\x7F]) - * [[:blank:]] blank (== [\t ]) - * [[:cntrl:]] control (== [\x00-\x1F\x7F]) - * [[:digit:]] digits (== [0-9]) - * [[:graph:]] graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]) - * [[:lower:]] lower case (== [a-z]) - * [[:print:]] printable (== [ -~] == [ [:graph:]]) - * [[:punct:]] punctuation (== [!-/:-@[-`{-~]) - * [[:space:]] whitespace (== [\t\n\v\f\r ]) - * [[:upper:]] upper case (== [A-Z]) - * [[:word:]] word characters (== [0-9A-Za-z_]) - * [[:xdigit:]] hex digit (== [0-9A-Fa-f]) - * ``` - * - * Unicode character classes are those in [unicode.Categories] and [unicode.Scripts]. - */ -namespace syntax { - /** - * Flags control the behavior of the parser and record information about regexp context. - */ - interface Flags extends Number{} -} - -namespace store { - /** - * Store defines a concurrent safe in memory key-value data store. - */ - interface Store { - } - interface Store { - /** - * Reset clears the store and replaces the store data with a - * shallow copy of the provided newData. - */ - reset(newData: _TygojaDict): void - } - interface Store { - /** - * Length returns the current number of elements in the store. - */ - length(): number - } - interface Store { - /** - * RemoveAll removes all the existing store entries. - */ - removeAll(): void - } - interface Store { - /** - * Remove removes a single entry from the store. - * - * Remove does nothing if key doesn't exist in the store. - */ - remove(key: K): void - } - interface Store { - /** - * Has checks if element with the specified key exist or not. - */ - has(key: K): boolean - } - interface Store { - /** - * Get returns a single element value from the store. - * - * If key is not set, the zero T value is returned. - */ - get(key: K): T - } - interface Store { - /** - * GetOk is similar to Get but returns also a boolean indicating whether the key exists or not. - */ - getOk(key: K): [T, boolean] - } - interface Store { - /** - * GetAll returns a shallow copy of the current store data. - */ - getAll(): _TygojaDict - } - interface Store { - /** - * Values returns a slice with all of the current store values. - */ - values(): Array - } - interface Store { - /** - * Set sets (or overwrite if already exists) a new value for key. - */ - set(key: K, value: T): void - } - interface Store { - /** - * SetFunc sets (or overwrite if already exists) a new value resolved - * from the function callback for the provided key. - * - * The function callback receives as argument the old store element value (if exists). - * If there is no old store element, the argument will be the T zero value. - * - * Example: - * - * ``` - * s := store.New[string, int](nil) - * s.SetFunc("count", func(old int) int { - * return old + 1 - * }) - * ``` - */ - setFunc(key: K, fn: (old: T) => T): void - } - interface Store { - /** - * GetOrSet retrieves a single existing value for the provided key - * or stores a new one if it doesn't exist. - */ - getOrSet(key: K, setFunc: () => T): T - } - interface Store { - /** - * SetIfLessThanLimit sets (or overwrite if already exist) a new value for key. - * - * This method is similar to Set() but **it will skip adding new elements** - * to the store if the store length has reached the specified limit. - * false is returned if maxAllowedElements limit is reached. - */ - setIfLessThanLimit(key: K, value: T, maxAllowedElements: number): boolean - } - interface Store { - /** - * UnmarshalJSON implements [json.Unmarshaler] and imports the - * provided JSON data into the store. - * - * The store entries that match with the ones from the data will be overwritten with the new value. - */ - unmarshalJSON(data: string|Array): void - } - interface Store { - /** - * MarshalJSON implements [json.Marshaler] and export the current - * store data into valid JSON. - */ - marshalJSON(): string|Array - } -} - namespace hook { /** * Event implements [Resolver] and it is intended to be used as a base @@ -18253,237 +18956,285 @@ namespace hook { * TaggedHook defines a proxy hook which register handlers that are triggered only * if the TaggedHook.tags are empty or includes at least one of the event data tag(s). */ - type _stgWfis = mainHook - interface TaggedHook extends _stgWfis { + type _saVEmzP = mainHook + interface TaggedHook extends _saVEmzP { } } -namespace mailer { +namespace router { + // @ts-ignore + import validation = ozzo_validation /** - * Message defines a generic email message struct. + * ApiError defines the struct for a basic api error response. */ - interface Message { - from: { address: string; name?: string; } - to: Array<{ address: string; name?: string; }> - bcc: Array<{ address: string; name?: string; }> - cc: Array<{ address: string; name?: string; }> - subject: string - html: string - text: string - headers: _TygojaDict - attachments: _TygojaDict - inlineAttachments: _TygojaDict + interface ApiError { + data: _TygojaDict + message: string + status: number + } + interface ApiError { + /** + * Error makes it compatible with the `error` interface. + */ + error(): string + } + interface ApiError { + /** + * RawData returns the unformatted error data (could be an internal error, text, etc.) + */ + rawData(): any + } + interface ApiError { + /** + * Is reports whether the current ApiError wraps the target. + */ + is(target: Error): boolean } /** - * Mailer defines a base mail client interface. - */ - interface Mailer { - [key:string]: any; - /** - * Send sends an email with the provided Message. - */ - send(message: Message): void - } -} - -/** - * Package types implements some commonly used db serializable types - * like datetime, json, etc. - */ -namespace types { - /** - * DateTime represents a [time.Time] instance in UTC that is wrapped - * and serialized using the app default date layout. - */ - interface DateTime { - } - interface DateTime { - /** - * Time returns the internal [time.Time] instance. - */ - time(): time.Time - } - interface DateTime { - /** - * Add returns a new DateTime based on the current DateTime + the specified duration. - */ - add(duration: time.Duration): DateTime - } - interface DateTime { - /** - * Sub returns a [time.Duration] by subtracting the specified DateTime from the current one. - * - * If the result exceeds the maximum (or minimum) value that can be stored in a [time.Duration], - * the maximum (or minimum) duration will be returned. - */ - sub(u: DateTime): time.Duration - } - interface DateTime { - /** - * AddDate returns a new DateTime based on the current one + duration. - * - * It follows the same rules as [time.AddDate]. - */ - addDate(years: number, months: number, days: number): DateTime - } - interface DateTime { - /** - * After reports whether the current DateTime instance is after u. - */ - after(u: DateTime): boolean - } - interface DateTime { - /** - * Before reports whether the current DateTime instance is before u. - */ - before(u: DateTime): boolean - } - interface DateTime { - /** - * Compare compares the current DateTime instance with u. - * If the current instance is before u, it returns -1. - * If the current instance is after u, it returns +1. - * If they're the same, it returns 0. - */ - compare(u: DateTime): number - } - interface DateTime { - /** - * Equal reports whether the current DateTime and u represent the same time instant. - * Two DateTime can be equal even if they are in different locations. - * For example, 6:00 +0200 and 4:00 UTC are Equal. - */ - equal(u: DateTime): boolean - } - interface DateTime { - /** - * Unix returns the current DateTime as a Unix time, aka. - * the number of seconds elapsed since January 1, 1970 UTC. - */ - unix(): number - } - interface DateTime { - /** - * IsZero checks whether the current DateTime instance has zero time value. - */ - isZero(): boolean - } - interface DateTime { - /** - * String serializes the current DateTime instance into a formatted - * UTC date string. - * - * The zero value is serialized to an empty string. - */ - string(): string - } - interface DateTime { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface DateTime { - /** - * UnmarshalJSON implements the [json.Unmarshaler] interface. - */ - unmarshalJSON(b: string|Array): void - } - interface DateTime { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface DateTime { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current DateTime instance. - */ - scan(value: any): void - } - /** - * GeoPoint defines a struct for storing geo coordinates as serialized json object - * (e.g. {lon:0,lat:0}). + * Event specifies based Route handler event that is usually intended + * to be embedded as part of a custom event struct. * - * Note: using object notation and not a plain array to avoid the confusion - * as there doesn't seem to be a fixed standard for the coordinates order. + * NB! It is expected that the Response and Request fields are always set. */ - interface GeoPoint { - lon: number - lat: number + type _sICgySM = hook.Event + interface Event extends _sICgySM { + response: http.ResponseWriter + request?: http.Request } - interface GeoPoint { + interface Event { /** - * String returns the string representation of the current GeoPoint instance. - */ - string(): string - } - interface GeoPoint { - /** - * AsMap implements [core.mapExtractor] and returns a value suitable - * to be used in an API rule expression. - */ - asMap(): _TygojaDict - } - interface GeoPoint { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface GeoPoint { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current GeoPoint instance. + * Written reports whether the current response has already been written. * - * The value argument could be nil (no-op), another GeoPoint instance, - * map or serialized json object with lat-lon props. + * This method always returns false if e.ResponseWritter doesn't implement the WriteTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). */ - scan(value: any): void + written(): boolean + } + interface Event { + /** + * Status reports the status code of the current response. + * + * This method always returns 0 if e.Response doesn't implement the StatusTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + status(): number + } + interface Event { + /** + * Flush flushes buffered data to the current response. + * + * Returns [http.ErrNotSupported] if e.Response doesn't implement the [http.Flusher] interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + flush(): void + } + interface Event { + /** + * IsTLS reports whether the connection on which the request was received is TLS. + */ + isTLS(): boolean + } + interface Event { + /** + * SetCookie is an alias for [http.SetCookie]. + * + * SetCookie adds a Set-Cookie header to the current response's headers. + * The provided cookie must have a valid Name. + * Invalid cookies may be silently dropped. + */ + setCookie(cookie: http.Cookie): void + } + interface Event { + /** + * RemoteIP returns the IP address of the client that sent the request. + * + * IPv6 addresses are returned expanded. + * For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001". + * + * Note that if you are behind reverse proxy(ies), this method returns + * the IP of the last connecting proxy. + */ + remoteIP(): string + } + interface Event { + /** + * FindUploadedFiles extracts all form files of "key" from a http request + * and returns a slice with filesystem.File instances (if any). + */ + findUploadedFiles(key: string): Array<(filesystem.File | undefined)> + } + interface Event { + /** + * Get retrieves single value from the current event data store. + */ + get(key: string): any + } + interface Event { + /** + * GetAll returns a copy of the current event data store. + */ + getAll(): _TygojaDict + } + interface Event { + /** + * Set saves single value into the current event data store. + */ + set(key: string, value: any): void + } + interface Event { + /** + * SetAll saves all items from m into the current event data store. + */ + setAll(m: _TygojaDict): void + } + interface Event { + /** + * String writes a plain string response. + */ + string(status: number, data: string): void + } + interface Event { + /** + * HTML writes an HTML response. + */ + html(status: number, data: string): void + } + interface Event { + /** + * JSON writes a JSON response. + * + * It also provides a generic response data fields picker if the "fields" query parameter is set. + * For example, if you are requesting `?fields=a,b` for `e.JSON(200, map[string]int{ "a":1, "b":2, "c":3 })`, + * it should result in a JSON response like: `{"a":1, "b": 2}`. + */ + json(status: number, data: any): void + } + interface Event { + /** + * XML writes an XML response. + * It automatically prepends the generic [xml.Header] string to the response. + */ + xml(status: number, data: any): void + } + interface Event { + /** + * Stream streams the specified reader into the response. + */ + stream(status: number, contentType: string, reader: io.Reader): void + } + interface Event { + /** + * Blob writes a blob (bytes slice) response. + */ + blob(status: number, contentType: string, b: string|Array): void + } + interface Event { + /** + * FileFS serves the specified filename from fsys. + * + * It is similar to [echo.FileFS] for consistency with earlier versions. + */ + fileFS(fsys: fs.FS, filename: string): void + } + interface Event { + /** + * NoContent writes a response with no body (ex. 204). + */ + noContent(status: number): void + } + interface Event { + /** + * Redirect writes a redirect response to the specified url. + * The status code must be in between 300 – 399 range. + */ + redirect(status: number, url: string): void + } + interface Event { + error(status: number, message: string, errData: any): (ApiError) + } + interface Event { + badRequestError(message: string, errData: any): (ApiError) + } + interface Event { + notFoundError(message: string, errData: any): (ApiError) + } + interface Event { + forbiddenError(message: string, errData: any): (ApiError) + } + interface Event { + unauthorizedError(message: string, errData: any): (ApiError) + } + interface Event { + tooManyRequestsError(message: string, errData: any): (ApiError) + } + interface Event { + internalServerError(message: string, errData: any): (ApiError) + } + interface Event { + /** + * BindBody unmarshal the request body into the provided dst. + * + * dst must be either a struct pointer or map[string]any. + * + * The rules how the body will be scanned depends on the request Content-Type. + * + * Currently the following Content-Types are supported: + * ``` + * - application/json + * - text/xml, application/xml + * - multipart/form-data, application/x-www-form-urlencoded + * ``` + * + * Respectively the following struct tags are supported (again, which one will be used depends on the Content-Type): + * ``` + * - "json" (json body)- uses the builtin Go json package for unmarshaling. + * - "xml" (xml body) - uses the builtin Go xml package for unmarshaling. + * - "form" (form data) - utilizes the custom [router.UnmarshalRequestData] method. + * ``` + * + * NB! When dst is a struct make sure that it doesn't have public fields + * that shouldn't be bindable and it is advisible such fields to be unexported + * or have a separate struct just for the binding. For example: + * + * ``` + * data := struct{ + * somethingPrivate string + * + * Title string `json:"title" form:"title"` + * Total int `json:"total" form:"total"` + * } + * err := e.BindBody(&data) + * ``` + */ + bindBody(dst: any): void } /** - * JSONArray defines a slice that is safe for json and db read/write. + * Router defines a thin wrapper around the standard Go [http.ServeMux] by + * adding support for routing sub-groups, middlewares and other common utils. + * + * Example: + * + * ``` + * r := NewRouter[*MyEvent](eventFactory) + * + * // middlewares + * r.BindFunc(m1, m2) + * + * // routes + * r.GET("/test", handler1) + * + * // sub-routers/groups + * api := r.Group("/api") + * api.GET("/admins", handler2) + * + * // generate a http.ServeMux instance based on the router configurations + * mux, _ := r.BuildMux() + * + * http.ListenAndServe("localhost:8090", mux) + * ``` */ - interface JSONArray extends Array{} - /** - * JSONMap defines a map that is safe for json and db read/write. - */ - interface JSONMap extends _TygojaDict{} - /** - * JSONRaw defines a json value type that is safe for db read/write. - */ - interface JSONRaw extends Array{} - interface JSONRaw { - /** - * String returns the current JSONRaw instance as a json encoded string. - */ - string(): string - } - interface JSONRaw { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface JSONRaw { - /** - * UnmarshalJSON implements the [json.Unmarshaler] interface. - */ - unmarshalJSON(b: string|Array): void - } - interface JSONRaw { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface JSONRaw { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current JSONRaw instance. - */ - scan(value: any): void + type _snZAahr = RouterGroup + interface Router extends _snZAahr { } } @@ -18638,496 +19389,6 @@ namespace auth { } } -/** - * Package slog provides structured logging, - * in which log records include a message, - * a severity level, and various other attributes - * expressed as key-value pairs. - * - * It defines a type, [Logger], - * which provides several methods (such as [Logger.Info] and [Logger.Error]) - * for reporting events of interest. - * - * Each Logger is associated with a [Handler]. - * A Logger output method creates a [Record] from the method arguments - * and passes it to the Handler, which decides how to handle it. - * There is a default Logger accessible through top-level functions - * (such as [Info] and [Error]) that call the corresponding Logger methods. - * - * A log record consists of a time, a level, a message, and a set of key-value - * pairs, where the keys are strings and the values may be of any type. - * As an example, - * - * ``` - * slog.Info("hello", "count", 3) - * ``` - * - * creates a record containing the time of the call, - * a level of Info, the message "hello", and a single - * pair with key "count" and value 3. - * - * The [Info] top-level function calls the [Logger.Info] method on the default Logger. - * In addition to [Logger.Info], there are methods for Debug, Warn and Error levels. - * Besides these convenience methods for common levels, - * there is also a [Logger.Log] method which takes the level as an argument. - * Each of these methods has a corresponding top-level function that uses the - * default logger. - * - * The default handler formats the log record's message, time, level, and attributes - * as a string and passes it to the [log] package. - * - * ``` - * 2022/11/08 15:28:26 INFO hello count=3 - * ``` - * - * For more control over the output format, create a logger with a different handler. - * This statement uses [New] to create a new logger with a [TextHandler] - * that writes structured records in text form to standard error: - * - * ``` - * logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) - * ``` - * - * [TextHandler] output is a sequence of key=value pairs, easily and unambiguously - * parsed by machine. This statement: - * - * ``` - * logger.Info("hello", "count", 3) - * ``` - * - * produces this output: - * - * ``` - * time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3 - * ``` - * - * The package also provides [JSONHandler], whose output is line-delimited JSON: - * - * ``` - * logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) - * logger.Info("hello", "count", 3) - * ``` - * - * produces this output: - * - * ``` - * {"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3} - * ``` - * - * Both [TextHandler] and [JSONHandler] can be configured with [HandlerOptions]. - * There are options for setting the minimum level (see Levels, below), - * displaying the source file and line of the log call, and - * modifying attributes before they are logged. - * - * Setting a logger as the default with - * - * ``` - * slog.SetDefault(logger) - * ``` - * - * will cause the top-level functions like [Info] to use it. - * [SetDefault] also updates the default logger used by the [log] package, - * so that existing applications that use [log.Printf] and related functions - * will send log records to the logger's handler without needing to be rewritten. - * - * Some attributes are common to many log calls. - * For example, you may wish to include the URL or trace identifier of a server request - * with all log events arising from the request. - * Rather than repeat the attribute with every log call, you can use [Logger.With] - * to construct a new Logger containing the attributes: - * - * ``` - * logger2 := logger.With("url", r.URL) - * ``` - * - * The arguments to With are the same key-value pairs used in [Logger.Info]. - * The result is a new Logger with the same handler as the original, but additional - * attributes that will appear in the output of every call. - * - * # Levels - * - * A [Level] is an integer representing the importance or severity of a log event. - * The higher the level, the more severe the event. - * This package defines constants for the most common levels, - * but any int can be used as a level. - * - * In an application, you may wish to log messages only at a certain level or greater. - * One common configuration is to log messages at Info or higher levels, - * suppressing debug logging until it is needed. - * The built-in handlers can be configured with the minimum level to output by - * setting [HandlerOptions.Level]. - * The program's `main` function typically does this. - * The default value is LevelInfo. - * - * Setting the [HandlerOptions.Level] field to a [Level] value - * fixes the handler's minimum level throughout its lifetime. - * Setting it to a [LevelVar] allows the level to be varied dynamically. - * A LevelVar holds a Level and is safe to read or write from multiple - * goroutines. - * To vary the level dynamically for an entire program, first initialize - * a global LevelVar: - * - * ``` - * var programLevel = new(slog.LevelVar) // Info by default - * ``` - * - * Then use the LevelVar to construct a handler, and make it the default: - * - * ``` - * h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel}) - * slog.SetDefault(slog.New(h)) - * ``` - * - * Now the program can change its logging level with a single statement: - * - * ``` - * programLevel.Set(slog.LevelDebug) - * ``` - * - * # Groups - * - * Attributes can be collected into groups. - * A group has a name that is used to qualify the names of its attributes. - * How this qualification is displayed depends on the handler. - * [TextHandler] separates the group and attribute names with a dot. - * [JSONHandler] treats each group as a separate JSON object, with the group name as the key. - * - * Use [Group] to create a Group attribute from a name and a list of key-value pairs: - * - * ``` - * slog.Group("request", - * "method", r.Method, - * "url", r.URL) - * ``` - * - * TextHandler would display this group as - * - * ``` - * request.method=GET request.url=http://example.com - * ``` - * - * JSONHandler would display it as - * - * ``` - * "request":{"method":"GET","url":"http://example.com"} - * ``` - * - * Use [Logger.WithGroup] to qualify all of a Logger's output - * with a group name. Calling WithGroup on a Logger results in a - * new Logger with the same Handler as the original, but with all - * its attributes qualified by the group name. - * - * This can help prevent duplicate attribute keys in large systems, - * where subsystems might use the same keys. - * Pass each subsystem a different Logger with its own group name so that - * potential duplicates are qualified: - * - * ``` - * logger := slog.Default().With("id", systemID) - * parserLogger := logger.WithGroup("parser") - * parseInput(input, parserLogger) - * ``` - * - * When parseInput logs with parserLogger, its keys will be qualified with "parser", - * so even if it uses the common key "id", the log line will have distinct keys. - * - * # Contexts - * - * Some handlers may wish to include information from the [context.Context] that is - * available at the call site. One example of such information - * is the identifier for the current span when tracing is enabled. - * - * The [Logger.Log] and [Logger.LogAttrs] methods take a context as a first - * argument, as do their corresponding top-level functions. - * - * Although the convenience methods on Logger (Info and so on) and the - * corresponding top-level functions do not take a context, the alternatives ending - * in "Context" do. For example, - * - * ``` - * slog.InfoContext(ctx, "message") - * ``` - * - * It is recommended to pass a context to an output method if one is available. - * - * # Attrs and Values - * - * An [Attr] is a key-value pair. The Logger output methods accept Attrs as well as - * alternating keys and values. The statement - * - * ``` - * slog.Info("hello", slog.Int("count", 3)) - * ``` - * - * behaves the same as - * - * ``` - * slog.Info("hello", "count", 3) - * ``` - * - * There are convenience constructors for [Attr] such as [Int], [String], and [Bool] - * for common types, as well as the function [Any] for constructing Attrs of any - * type. - * - * The value part of an Attr is a type called [Value]. - * Like an [any], a Value can hold any Go value, - * but it can represent typical values, including all numbers and strings, - * without an allocation. - * - * For the most efficient log output, use [Logger.LogAttrs]. - * It is similar to [Logger.Log] but accepts only Attrs, not alternating - * keys and values; this allows it, too, to avoid allocation. - * - * The call - * - * ``` - * logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3)) - * ``` - * - * is the most efficient way to achieve the same output as - * - * ``` - * slog.InfoContext(ctx, "hello", "count", 3) - * ``` - * - * # Customizing a type's logging behavior - * - * If a type implements the [LogValuer] interface, the [Value] returned from its LogValue - * method is used for logging. You can use this to control how values of the type - * appear in logs. For example, you can redact secret information like passwords, - * or gather a struct's fields in a Group. See the examples under [LogValuer] for - * details. - * - * A LogValue method may return a Value that itself implements [LogValuer]. The [Value.Resolve] - * method handles these cases carefully, avoiding infinite loops and unbounded recursion. - * Handler authors and others may wish to use [Value.Resolve] instead of calling LogValue directly. - * - * # Wrapping output methods - * - * The logger functions use reflection over the call stack to find the file name - * and line number of the logging call within the application. This can produce - * incorrect source information for functions that wrap slog. For instance, if you - * define this function in file mylog.go: - * - * ``` - * func Infof(logger *slog.Logger, format string, args ...any) { - * logger.Info(fmt.Sprintf(format, args...)) - * } - * ``` - * - * and you call it like this in main.go: - * - * ``` - * Infof(slog.Default(), "hello, %s", "world") - * ``` - * - * then slog will report the source file as mylog.go, not main.go. - * - * A correct implementation of Infof will obtain the source location - * (pc) and pass it to NewRecord. - * The Infof function in the package-level example called "wrapping" - * demonstrates how to do this. - * - * # Working with Records - * - * Sometimes a Handler will need to modify a Record - * before passing it on to another Handler or backend. - * A Record contains a mixture of simple public fields (e.g. Time, Level, Message) - * and hidden fields that refer to state (such as attributes) indirectly. This - * means that modifying a simple copy of a Record (e.g. by calling - * [Record.Add] or [Record.AddAttrs] to add attributes) - * may have unexpected effects on the original. - * Before modifying a Record, use [Record.Clone] to - * create a copy that shares no state with the original, - * or create a new Record with [NewRecord] - * and build up its Attrs by traversing the old ones with [Record.Attrs]. - * - * # Performance considerations - * - * If profiling your application demonstrates that logging is taking significant time, - * the following suggestions may help. - * - * If many log lines have a common attribute, use [Logger.With] to create a Logger with - * that attribute. The built-in handlers will format that attribute only once, at the - * call to [Logger.With]. The [Handler] interface is designed to allow that optimization, - * and a well-written Handler should take advantage of it. - * - * The arguments to a log call are always evaluated, even if the log event is discarded. - * If possible, defer computation so that it happens only if the value is actually logged. - * For example, consider the call - * - * ``` - * slog.Info("starting request", "url", r.URL.String()) // may compute String unnecessarily - * ``` - * - * The URL.String method will be called even if the logger discards Info-level events. - * Instead, pass the URL directly: - * - * ``` - * slog.Info("starting request", "url", &r.URL) // calls URL.String only if needed - * ``` - * - * The built-in [TextHandler] will call its String method, but only - * if the log event is enabled. - * Avoiding the call to String also preserves the structure of the underlying value. - * For example [JSONHandler] emits the components of the parsed URL as a JSON object. - * If you want to avoid eagerly paying the cost of the String call - * without causing the handler to potentially inspect the structure of the value, - * wrap the value in a fmt.Stringer implementation that hides its Marshal methods. - * - * You can also use the [LogValuer] interface to avoid unnecessary work in disabled log - * calls. Say you need to log some expensive value: - * - * ``` - * slog.Debug("frobbing", "value", computeExpensiveValue(arg)) - * ``` - * - * Even if this line is disabled, computeExpensiveValue will be called. - * To avoid that, define a type implementing LogValuer: - * - * ``` - * type expensive struct { arg int } - * - * func (e expensive) LogValue() slog.Value { - * return slog.AnyValue(computeExpensiveValue(e.arg)) - * } - * ``` - * - * Then use a value of that type in log calls: - * - * ``` - * slog.Debug("frobbing", "value", expensive{arg}) - * ``` - * - * Now computeExpensiveValue will only be called when the line is enabled. - * - * The built-in handlers acquire a lock before calling [io.Writer.Write] - * to ensure that exactly one [Record] is written at a time in its entirety. - * Although each log record has a timestamp, - * the built-in handlers do not use that time to sort the written records. - * User-defined handlers are responsible for their own locking and sorting. - * - * # Writing a handler - * - * For a guide to writing a custom handler, see https://golang.org/s/slog-handler-guide. - */ -namespace slog { - // @ts-ignore - import loginternal = internal - /** - * A Logger records structured information about each call to its - * Log, Debug, Info, Warn, and Error methods. - * For each call, it creates a [Record] and passes it to a [Handler]. - * - * To create a new Logger, call [New] or a Logger method - * that begins "With". - */ - interface Logger { - } - interface Logger { - /** - * Handler returns l's Handler. - */ - handler(): Handler - } - interface Logger { - /** - * With returns a Logger that includes the given attributes - * in each output operation. Arguments are converted to - * attributes as if by [Logger.Log]. - */ - with(...args: any[]): (Logger) - } - interface Logger { - /** - * WithGroup returns a Logger that starts a group, if name is non-empty. - * The keys of all attributes added to the Logger will be qualified by the given - * name. (How that qualification happens depends on the [Handler.WithGroup] - * method of the Logger's Handler.) - * - * If name is empty, WithGroup returns the receiver. - */ - withGroup(name: string): (Logger) - } - interface Logger { - /** - * Enabled reports whether l emits log records at the given context and level. - */ - enabled(ctx: context.Context, level: Level): boolean - } - interface Logger { - /** - * Log emits a log record with the current time and the given level and message. - * The Record's Attrs consist of the Logger's attributes followed by - * the Attrs specified by args. - * - * The attribute arguments are processed as follows: - * ``` - * - If an argument is an Attr, it is used as is. - * - If an argument is a string and this is not the last argument, - * the following argument is treated as the value and the two are combined - * into an Attr. - * - Otherwise, the argument is treated as a value with key "!BADKEY". - * ``` - */ - log(ctx: context.Context, level: Level, msg: string, ...args: any[]): void - } - interface Logger { - /** - * LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs. - */ - logAttrs(ctx: context.Context, level: Level, msg: string, ...attrs: Attr[]): void - } - interface Logger { - /** - * Debug logs at [LevelDebug]. - */ - debug(msg: string, ...args: any[]): void - } - interface Logger { - /** - * DebugContext logs at [LevelDebug] with the given context. - */ - debugContext(ctx: context.Context, msg: string, ...args: any[]): void - } - interface Logger { - /** - * Info logs at [LevelInfo]. - */ - info(msg: string, ...args: any[]): void - } - interface Logger { - /** - * InfoContext logs at [LevelInfo] with the given context. - */ - infoContext(ctx: context.Context, msg: string, ...args: any[]): void - } - interface Logger { - /** - * Warn logs at [LevelWarn]. - */ - warn(msg: string, ...args: any[]): void - } - interface Logger { - /** - * WarnContext logs at [LevelWarn] with the given context. - */ - warnContext(ctx: context.Context, msg: string, ...args: any[]): void - } - interface Logger { - /** - * Error logs at [LevelError]. - */ - error(msg: string, ...args: any[]): void - } - interface Logger { - /** - * ErrorContext logs at [LevelError] with the given context. - */ - errorContext(ctx: context.Context, msg: string, ...args: any[]): void - } -} - namespace subscriptions { /** * Broker defines a struct for managing subscriptions clients. @@ -19367,6 +19628,284 @@ namespace cron { } } +namespace exec { + /** + * Cmd represents an external command being prepared or run. + * + * A Cmd cannot be reused after calling its [Cmd.Run], [Cmd.Output] or [Cmd.CombinedOutput] + * methods. + */ + interface Cmd { + /** + * Path is the path of the command to run. + * + * This is the only field that must be set to a non-zero + * value. If Path is relative, it is evaluated relative + * to Dir. + */ + path: string + /** + * Args holds command line arguments, including the command as Args[0]. + * If the Args field is empty or nil, Run uses {Path}. + * + * In typical use, both Path and Args are set by calling Command. + */ + args: Array + /** + * Env specifies the environment of the process. + * Each entry is of the form "key=value". + * If Env is nil, the new process uses the current process's + * environment. + * If Env contains duplicate environment keys, only the last + * value in the slice for each duplicate key is used. + * As a special case on Windows, SYSTEMROOT is always added if + * missing and not explicitly set to the empty string. + */ + env: Array + /** + * Dir specifies the working directory of the command. + * If Dir is the empty string, Run runs the command in the + * calling process's current directory. + */ + dir: string + /** + * Stdin specifies the process's standard input. + * + * If Stdin is nil, the process reads from the null device (os.DevNull). + * + * If Stdin is an *os.File, the process's standard input is connected + * directly to that file. + * + * Otherwise, during the execution of the command a separate + * goroutine reads from Stdin and delivers that data to the command + * over a pipe. In this case, Wait does not complete until the goroutine + * stops copying, either because it has reached the end of Stdin + * (EOF or a read error), or because writing to the pipe returned an error, + * or because a nonzero WaitDelay was set and expired. + */ + stdin: io.Reader + /** + * Stdout and Stderr specify the process's standard output and error. + * + * If either is nil, Run connects the corresponding file descriptor + * to the null device (os.DevNull). + * + * If either is an *os.File, the corresponding output from the process + * is connected directly to that file. + * + * Otherwise, during the execution of the command a separate goroutine + * reads from the process over a pipe and delivers that data to the + * corresponding Writer. In this case, Wait does not complete until the + * goroutine reaches EOF or encounters an error or a nonzero WaitDelay + * expires. + * + * If Stdout and Stderr are the same writer, and have a type that can + * be compared with ==, at most one goroutine at a time will call Write. + */ + stdout: io.Writer + stderr: io.Writer + /** + * ExtraFiles specifies additional open files to be inherited by the + * new process. It does not include standard input, standard output, or + * standard error. If non-nil, entry i becomes file descriptor 3+i. + * + * ExtraFiles is not supported on Windows. + */ + extraFiles: Array<(os.File | undefined)> + /** + * SysProcAttr holds optional, operating system-specific attributes. + * Run passes it to os.StartProcess as the os.ProcAttr's Sys field. + */ + sysProcAttr?: syscall.SysProcAttr + /** + * Process is the underlying process, once started. + */ + process?: os.Process + /** + * ProcessState contains information about an exited process. + * If the process was started successfully, Wait or Run will + * populate its ProcessState when the command completes. + */ + processState?: os.ProcessState + err: Error // LookPath error, if any. + /** + * If Cancel is non-nil, the command must have been created with + * CommandContext and Cancel will be called when the command's + * Context is done. By default, CommandContext sets Cancel to + * call the Kill method on the command's Process. + * + * Typically a custom Cancel will send a signal to the command's + * Process, but it may instead take other actions to initiate cancellation, + * such as closing a stdin or stdout pipe or sending a shutdown request on a + * network socket. + * + * If the command exits with a success status after Cancel is + * called, and Cancel does not return an error equivalent to + * os.ErrProcessDone, then Wait and similar methods will return a non-nil + * error: either an error wrapping the one returned by Cancel, + * or the error from the Context. + * (If the command exits with a non-success status, or Cancel + * returns an error that wraps os.ErrProcessDone, Wait and similar methods + * continue to return the command's usual exit status.) + * + * If Cancel is set to nil, nothing will happen immediately when the command's + * Context is done, but a nonzero WaitDelay will still take effect. That may + * be useful, for example, to work around deadlocks in commands that do not + * support shutdown signals but are expected to always finish quickly. + * + * Cancel will not be called if Start returns a non-nil error. + */ + cancel: () => void + /** + * If WaitDelay is non-zero, it bounds the time spent waiting on two sources + * of unexpected delay in Wait: a child process that fails to exit after the + * associated Context is canceled, and a child process that exits but leaves + * its I/O pipes unclosed. + * + * The WaitDelay timer starts when either the associated Context is done or a + * call to Wait observes that the child process has exited, whichever occurs + * first. When the delay has elapsed, the command shuts down the child process + * and/or its I/O pipes. + * + * If the child process has failed to exit — perhaps because it ignored or + * failed to receive a shutdown signal from a Cancel function, or because no + * Cancel function was set — then it will be terminated using os.Process.Kill. + * + * Then, if the I/O pipes communicating with the child process are still open, + * those pipes are closed in order to unblock any goroutines currently blocked + * on Read or Write calls. + * + * If pipes are closed due to WaitDelay, no Cancel call has occurred, + * and the command has otherwise exited with a successful status, Wait and + * similar methods will return ErrWaitDelay instead of nil. + * + * If WaitDelay is zero (the default), I/O pipes will be read until EOF, + * which might not occur until orphaned subprocesses of the command have + * also closed their descriptors for the pipes. + */ + waitDelay: time.Duration + } + interface Cmd { + /** + * String returns a human-readable description of c. + * It is intended only for debugging. + * In particular, it is not suitable for use as input to a shell. + * The output of String may vary across Go releases. + */ + string(): string + } + interface Cmd { + /** + * Run starts the specified command and waits for it to complete. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command starts but does not complete successfully, the error is of + * type [*ExitError]. Other error types may be returned for other situations. + * + * If the calling goroutine has locked the operating system thread + * with [runtime.LockOSThread] and modified any inheritable OS-level + * thread state (for example, Linux or Plan 9 name spaces), the new + * process will inherit the caller's thread state. + */ + run(): void + } + interface Cmd { + /** + * Start starts the specified command but does not wait for it to complete. + * + * If Start returns successfully, the c.Process field will be set. + * + * After a successful call to Start the [Cmd.Wait] method must be called in + * order to release associated system resources. + */ + start(): void + } + interface Cmd { + /** + * Wait waits for the command to exit and waits for any copying to + * stdin or copying from stdout or stderr to complete. + * + * The command must have been started by [Cmd.Start]. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command fails to run or doesn't complete successfully, the + * error is of type [*ExitError]. Other error types may be + * returned for I/O problems. + * + * If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits + * for the respective I/O loop copying to or from the process to complete. + * + * Wait releases any resources associated with the [Cmd]. + */ + wait(): void + } + interface Cmd { + /** + * Output runs the command and returns its standard output. + * Any returned error will usually be of type [*ExitError]. + * If c.Stderr was nil, Output populates [ExitError.Stderr]. + */ + output(): string|Array + } + interface Cmd { + /** + * CombinedOutput runs the command and returns its combined standard + * output and standard error. + */ + combinedOutput(): string|Array + } + interface Cmd { + /** + * StdinPipe returns a pipe that will be connected to the command's + * standard input when the command starts. + * The pipe will be closed automatically after [Cmd.Wait] sees the command exit. + * A caller need only call Close to force the pipe to close sooner. + * For example, if the command being run will not exit until standard input + * is closed, the caller must close the pipe. + */ + stdinPipe(): io.WriteCloser + } + interface Cmd { + /** + * StdoutPipe returns a pipe that will be connected to the command's + * standard output when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe. + * See the example for idiomatic usage. + */ + stdoutPipe(): io.ReadCloser + } + interface Cmd { + /** + * StderrPipe returns a pipe that will be connected to the command's + * standard error when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe. + * See the StdoutPipe example for idiomatic usage. + */ + stderrPipe(): io.ReadCloser + } + interface Cmd { + /** + * Environ returns a copy of the environment in which the command would be run + * as it is currently configured. + */ + environ(): Array + } +} + /** * Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. * In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. @@ -20449,323 +20988,31 @@ namespace cobra { } } -namespace search { +namespace mailer { /** - * Result defines the returned search result structure. + * Message defines a generic email message struct. */ - interface Result { - items: any - page: number - perPage: number - totalItems: number - totalPages: number + interface Message { + from: { address: string; name?: string; } + to: Array<{ address: string; name?: string; }> + bcc: Array<{ address: string; name?: string; }> + cc: Array<{ address: string; name?: string; }> + subject: string + html: string + text: string + headers: _TygojaDict + attachments: _TygojaDict + inlineAttachments: _TygojaDict } /** - * ResolverResult defines a single FieldResolver.Resolve() successfully parsed result. + * Mailer defines a base mail client interface. */ - interface ResolverResult { + interface Mailer { + [key:string]: any; /** - * Identifier is the plain SQL identifier/column that will be used - * in the final db expression as left or right operand. + * Send sends an email with the provided Message. */ - identifier: string - /** - * NoCoalesce instructs to not use COALESCE or NULL fallbacks - * when building the identifier expression. - */ - noCoalesce: boolean - /** - * Params is a map with db placeholder->value pairs that will be added - * to the query when building both resolved operands/sides in a single expression. - */ - params: dbx.Params - /** - * MultiMatchSubQuery is an optional sub query expression that will be added - * in addition to the combined ResolverResult expression during build. - */ - multiMatchSubQuery: dbx.Expression - /** - * AfterBuild is an optional function that will be called after building - * and combining the result of both resolved operands/sides in a single expression. - */ - afterBuild: (expr: dbx.Expression) => dbx.Expression - } -} - -namespace router { - // @ts-ignore - import validation = ozzo_validation - /** - * ApiError defines the struct for a basic api error response. - */ - interface ApiError { - data: _TygojaDict - message: string - status: number - } - interface ApiError { - /** - * Error makes it compatible with the `error` interface. - */ - error(): string - } - interface ApiError { - /** - * RawData returns the unformatted error data (could be an internal error, text, etc.) - */ - rawData(): any - } - interface ApiError { - /** - * Is reports whether the current ApiError wraps the target. - */ - is(target: Error): boolean - } - /** - * Event specifies based Route handler event that is usually intended - * to be embedded as part of a custom event struct. - * - * NB! It is expected that the Response and Request fields are always set. - */ - type _sycTHXl = hook.Event - interface Event extends _sycTHXl { - response: http.ResponseWriter - request?: http.Request - } - interface Event { - /** - * Written reports whether the current response has already been written. - * - * This method always returns false if e.ResponseWritter doesn't implement the WriteTracker interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - written(): boolean - } - interface Event { - /** - * Status reports the status code of the current response. - * - * This method always returns 0 if e.Response doesn't implement the StatusTracker interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - status(): number - } - interface Event { - /** - * Flush flushes buffered data to the current response. - * - * Returns [http.ErrNotSupported] if e.Response doesn't implement the [http.Flusher] interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - flush(): void - } - interface Event { - /** - * IsTLS reports whether the connection on which the request was received is TLS. - */ - isTLS(): boolean - } - interface Event { - /** - * SetCookie is an alias for [http.SetCookie]. - * - * SetCookie adds a Set-Cookie header to the current response's headers. - * The provided cookie must have a valid Name. - * Invalid cookies may be silently dropped. - */ - setCookie(cookie: http.Cookie): void - } - interface Event { - /** - * RemoteIP returns the IP address of the client that sent the request. - * - * IPv6 addresses are returned expanded. - * For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001". - * - * Note that if you are behind reverse proxy(ies), this method returns - * the IP of the last connecting proxy. - */ - remoteIP(): string - } - interface Event { - /** - * FindUploadedFiles extracts all form files of "key" from a http request - * and returns a slice with filesystem.File instances (if any). - */ - findUploadedFiles(key: string): Array<(filesystem.File | undefined)> - } - interface Event { - /** - * Get retrieves single value from the current event data store. - */ - get(key: string): any - } - interface Event { - /** - * GetAll returns a copy of the current event data store. - */ - getAll(): _TygojaDict - } - interface Event { - /** - * Set saves single value into the current event data store. - */ - set(key: string, value: any): void - } - interface Event { - /** - * SetAll saves all items from m into the current event data store. - */ - setAll(m: _TygojaDict): void - } - interface Event { - /** - * String writes a plain string response. - */ - string(status: number, data: string): void - } - interface Event { - /** - * HTML writes an HTML response. - */ - html(status: number, data: string): void - } - interface Event { - /** - * JSON writes a JSON response. - * - * It also provides a generic response data fields picker if the "fields" query parameter is set. - * For example, if you are requesting `?fields=a,b` for `e.JSON(200, map[string]int{ "a":1, "b":2, "c":3 })`, - * it should result in a JSON response like: `{"a":1, "b": 2}`. - */ - json(status: number, data: any): void - } - interface Event { - /** - * XML writes an XML response. - * It automatically prepends the generic [xml.Header] string to the response. - */ - xml(status: number, data: any): void - } - interface Event { - /** - * Stream streams the specified reader into the response. - */ - stream(status: number, contentType: string, reader: io.Reader): void - } - interface Event { - /** - * Blob writes a blob (bytes slice) response. - */ - blob(status: number, contentType: string, b: string|Array): void - } - interface Event { - /** - * FileFS serves the specified filename from fsys. - * - * It is similar to [echo.FileFS] for consistency with earlier versions. - */ - fileFS(fsys: fs.FS, filename: string): void - } - interface Event { - /** - * NoContent writes a response with no body (ex. 204). - */ - noContent(status: number): void - } - interface Event { - /** - * Redirect writes a redirect response to the specified url. - * The status code must be in between 300 – 399 range. - */ - redirect(status: number, url: string): void - } - interface Event { - error(status: number, message: string, errData: any): (ApiError) - } - interface Event { - badRequestError(message: string, errData: any): (ApiError) - } - interface Event { - notFoundError(message: string, errData: any): (ApiError) - } - interface Event { - forbiddenError(message: string, errData: any): (ApiError) - } - interface Event { - unauthorizedError(message: string, errData: any): (ApiError) - } - interface Event { - tooManyRequestsError(message: string, errData: any): (ApiError) - } - interface Event { - internalServerError(message: string, errData: any): (ApiError) - } - interface Event { - /** - * BindBody unmarshal the request body into the provided dst. - * - * dst must be either a struct pointer or map[string]any. - * - * The rules how the body will be scanned depends on the request Content-Type. - * - * Currently the following Content-Types are supported: - * ``` - * - application/json - * - text/xml, application/xml - * - multipart/form-data, application/x-www-form-urlencoded - * ``` - * - * Respectively the following struct tags are supported (again, which one will be used depends on the Content-Type): - * ``` - * - "json" (json body)- uses the builtin Go json package for unmarshaling. - * - "xml" (xml body) - uses the builtin Go xml package for unmarshaling. - * - "form" (form data) - utilizes the custom [router.UnmarshalRequestData] method. - * ``` - * - * NB! When dst is a struct make sure that it doesn't have public fields - * that shouldn't be bindable and it is advisible such fields to be unexported - * or have a separate struct just for the binding. For example: - * - * ``` - * data := struct{ - * somethingPrivate string - * - * Title string `json:"title" form:"title"` - * Total int `json:"total" form:"total"` - * } - * err := e.BindBody(&data) - * ``` - */ - bindBody(dst: any): void - } - /** - * Router defines a thin wrapper around the standard Go [http.ServeMux] by - * adding support for routing sub-groups, middlewares and other common utils. - * - * Example: - * - * ``` - * r := NewRouter[*MyEvent](eventFactory) - * - * // middlewares - * r.BindFunc(m1, m2) - * - * // routes - * r.GET("/test", handler1) - * - * // sub-routers/groups - * api := r.Group("/api") - * api.GET("/admins", handler2) - * - * // generate a http.ServeMux instance based on the router configurations - * mux, _ := r.BuildMux() - * - * http.ListenAndServe("localhost:8090", mux) - * ``` - */ - type _slqDwTh = RouterGroup - interface Router extends _slqDwTh { + send(message: Message): void } } @@ -20789,6 +21036,655 @@ namespace io { } } +namespace syscall { + /** + * SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux. + * See user_namespaces(7). + * + * Note that User Namespaces are not available on a number of popular Linux + * versions (due to security issues), or are available but subject to AppArmor + * restrictions like in Ubuntu 24.04. + */ + interface SysProcIDMap { + containerID: number // Container ID. + hostID: number // Host ID. + size: number // Size. + } + // @ts-ignore + import errorspkg = errors + /** + * Credential holds user and group identities to be assumed + * by a child process started by [StartProcess]. + */ + interface Credential { + uid: number // User ID. + gid: number // Group ID. + groups: Array // Supplementary group IDs. + noSetGroups: boolean // If true, don't set supplementary groups + } + // @ts-ignore + import runtimesyscall = syscall + /** + * A Signal is a number describing a process signal. + * It implements the [os.Signal] interface. + */ + interface Signal extends Number{} + interface Signal { + signal(): void + } + interface Signal { + string(): string + } +} + +namespace time { + /** + * A Month specifies a month of the year (January = 1, ...). + */ + interface Month extends Number{} + interface Month { + /** + * String returns the English name of the month ("January", "February", ...). + */ + string(): string + } + /** + * A Weekday specifies a day of the week (Sunday = 0, ...). + */ + interface Weekday extends Number{} + interface Weekday { + /** + * String returns the English name of the day ("Sunday", "Monday", ...). + */ + string(): string + } + /** + * A Location maps time instants to the zone in use at that time. + * Typically, the Location represents the collection of time offsets + * in use in a geographical area. For many Locations the time offset varies + * depending on whether daylight savings time is in use at the time instant. + * + * Location is used to provide a time zone in a printed Time value and for + * calculations involving intervals that may cross daylight savings time + * boundaries. + */ + interface Location { + } + interface Location { + /** + * String returns a descriptive name for the time zone information, + * corresponding to the name argument to [LoadLocation] or [FixedZone]. + */ + string(): string + } +} + +namespace fs { +} + +namespace store { +} + +/** + * Package url parses URLs and implements query escaping. + */ +namespace url { + /** + * A URL represents a parsed URL (technically, a URI reference). + * + * The general form represented is: + * + * ``` + * [scheme:][//[userinfo@]host][/]path[?query][#fragment] + * ``` + * + * URLs that do not start with a slash after the scheme are interpreted as: + * + * ``` + * scheme:opaque[?query][#fragment] + * ``` + * + * The Host field contains the host and port subcomponents of the URL. + * When the port is present, it is separated from the host with a colon. + * When the host is an IPv6 address, it must be enclosed in square brackets: + * "[fe80::1]:80". The [net.JoinHostPort] function combines a host and port + * into a string suitable for the Host field, adding square brackets to + * the host when necessary. + * + * Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. + * A consequence is that it is impossible to tell which slashes in the Path were + * slashes in the raw URL and which were %2f. This distinction is rarely important, + * but when it is, the code should use the [URL.EscapedPath] method, which preserves + * the original encoding of Path. + * + * The RawPath field is an optional field which is only set when the default + * encoding of Path is different from the escaped path. See the EscapedPath method + * for more details. + * + * URL's String method uses the EscapedPath method to obtain the path. + */ + interface URL { + scheme: string + opaque: string // encoded opaque data + user?: Userinfo // username and password information + host: string // host or host:port (see Hostname and Port methods) + path: string // path (relative paths may omit leading slash) + rawPath: string // encoded path hint (see EscapedPath method) + omitHost: boolean // do not emit empty host (authority) + forceQuery: boolean // append a query ('?') even if RawQuery is empty + rawQuery: string // encoded query values, without '?' + fragment: string // fragment for references, without '#' + rawFragment: string // encoded fragment hint (see EscapedFragment method) + } + interface URL { + /** + * EscapedPath returns the escaped form of u.Path. + * In general there are multiple possible escaped forms of any path. + * EscapedPath returns u.RawPath when it is a valid escaping of u.Path. + * Otherwise EscapedPath ignores u.RawPath and computes an escaped + * form on its own. + * The [URL.String] and [URL.RequestURI] methods use EscapedPath to construct + * their results. + * In general, code should call EscapedPath instead of + * reading u.RawPath directly. + */ + escapedPath(): string + } + interface URL { + /** + * EscapedFragment returns the escaped form of u.Fragment. + * In general there are multiple possible escaped forms of any fragment. + * EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. + * Otherwise EscapedFragment ignores u.RawFragment and computes an escaped + * form on its own. + * The [URL.String] method uses EscapedFragment to construct its result. + * In general, code should call EscapedFragment instead of + * reading u.RawFragment directly. + */ + escapedFragment(): string + } + interface URL { + /** + * String reassembles the [URL] into a valid URL string. + * The general form of the result is one of: + * + * ``` + * scheme:opaque?query#fragment + * scheme://userinfo@host/path?query#fragment + * ``` + * + * If u.Opaque is non-empty, String uses the first form; + * otherwise it uses the second form. + * Any non-ASCII characters in host are escaped. + * To obtain the path, String uses u.EscapedPath(). + * + * In the second form, the following rules apply: + * ``` + * - if u.Scheme is empty, scheme: is omitted. + * - if u.User is nil, userinfo@ is omitted. + * - if u.Host is empty, host/ is omitted. + * - if u.Scheme and u.Host are empty and u.User is nil, + * the entire scheme://userinfo@host/ is omitted. + * - if u.Host is non-empty and u.Path begins with a /, + * the form host/path does not add its own /. + * - if u.RawQuery is empty, ?query is omitted. + * - if u.Fragment is empty, #fragment is omitted. + * ``` + */ + string(): string + } + interface URL { + /** + * Redacted is like [URL.String] but replaces any password with "xxxxx". + * Only the password in u.User is redacted. + */ + redacted(): string + } + /** + * Values maps a string key to a list of values. + * It is typically used for query parameters and form values. + * Unlike in the http.Header map, the keys in a Values map + * are case-sensitive. + */ + interface Values extends _TygojaDict{} + interface Values { + /** + * Get gets the first value associated with the given key. + * If there are no values associated with the key, Get returns + * the empty string. To access multiple values, use the map + * directly. + */ + get(key: string): string + } + interface Values { + /** + * Set sets the key to value. It replaces any existing + * values. + */ + set(key: string, value: string): void + } + interface Values { + /** + * Add adds the value to key. It appends to any existing + * values associated with key. + */ + add(key: string, value: string): void + } + interface Values { + /** + * Del deletes the values associated with key. + */ + del(key: string): void + } + interface Values { + /** + * Has checks whether a given key is set. + */ + has(key: string): boolean + } + interface Values { + /** + * Encode encodes the values into “URL encoded” form + * ("bar=baz&foo=quux") sorted by key. + */ + encode(): string + } + interface URL { + /** + * IsAbs reports whether the [URL] is absolute. + * Absolute means that it has a non-empty scheme. + */ + isAbs(): boolean + } + interface URL { + /** + * Parse parses a [URL] in the context of the receiver. The provided URL + * may be relative or absolute. Parse returns nil, err on parse + * failure, otherwise its return value is the same as [URL.ResolveReference]. + */ + parse(ref: string): (URL) + } + interface URL { + /** + * ResolveReference resolves a URI reference to an absolute URI from + * an absolute base URI u, per RFC 3986 Section 5.2. The URI reference + * may be relative or absolute. ResolveReference always returns a new + * [URL] instance, even if the returned URL is identical to either the + * base or reference. If ref is an absolute URL, then ResolveReference + * ignores base and returns a copy of ref. + */ + resolveReference(ref: URL): (URL) + } + interface URL { + /** + * Query parses RawQuery and returns the corresponding values. + * It silently discards malformed value pairs. + * To check errors use [ParseQuery]. + */ + query(): Values + } + interface URL { + /** + * RequestURI returns the encoded path?query or opaque?query + * string that would be used in an HTTP request for u. + */ + requestURI(): string + } + interface URL { + /** + * Hostname returns u.Host, stripping any valid port number if present. + * + * If the result is enclosed in square brackets, as literal IPv6 addresses are, + * the square brackets are removed from the result. + */ + hostname(): string + } + interface URL { + /** + * Port returns the port part of u.Host, without the leading colon. + * + * If u.Host doesn't contain a valid numeric port, Port returns an empty string. + */ + port(): string + } + interface URL { + marshalBinary(): string|Array + } + interface URL { + unmarshalBinary(text: string|Array): void + } + interface URL { + /** + * JoinPath returns a new [URL] with the provided path elements joined to + * any existing path and the resulting path cleaned of any ./ or ../ elements. + * Any sequences of multiple / characters will be reduced to a single /. + */ + joinPath(...elem: string[]): (URL) + } +} + +namespace context { +} + +namespace net { + /** + * Addr represents a network end point address. + * + * The two methods [Addr.Network] and [Addr.String] conventionally return strings + * that can be passed as the arguments to [Dial], but the exact form + * and meaning of the strings is up to the implementation. + */ + interface Addr { + [key:string]: any; + network(): string // name of the network (for example, "tcp", "udp") + string(): string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") + } + /** + * A Listener is a generic network listener for stream-oriented protocols. + * + * Multiple goroutines may invoke methods on a Listener simultaneously. + */ + interface Listener { + [key:string]: any; + /** + * Accept waits for and returns the next connection to the listener. + */ + accept(): Conn + /** + * Close closes the listener. + * Any blocked Accept operations will be unblocked and return errors. + */ + close(): void + /** + * Addr returns the listener's network address. + */ + addr(): Addr + } +} + +namespace jwt { + /** + * NumericDate represents a JSON numeric date value, as referenced at + * https://datatracker.ietf.org/doc/html/rfc7519#section-2. + */ + type _ssanSzt = time.Time + interface NumericDate extends _ssanSzt { + } + interface NumericDate { + /** + * MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch + * represented in NumericDate to a byte array, using the precision specified in TimePrecision. + */ + marshalJSON(): string|Array + } + interface NumericDate { + /** + * UnmarshalJSON is an implementation of the json.RawMessage interface and + * deserializes a [NumericDate] from a JSON representation, i.e. a + * [json.Number]. This number represents an UNIX epoch with either integer or + * non-integer seconds. + */ + unmarshalJSON(b: string|Array): void + } + /** + * ClaimStrings is basically just a slice of strings, but it can be either + * serialized from a string array or just a string. This type is necessary, + * since the "aud" claim can either be a single string or an array. + */ + interface ClaimStrings extends Array{} + interface ClaimStrings { + unmarshalJSON(data: string|Array): void + } + interface ClaimStrings { + marshalJSON(): string|Array + } +} + +namespace subscriptions { +} + +namespace cron { + /** + * Job defines a single registered cron job. + */ + interface Job { + } + interface Job { + /** + * Id returns the cron job id. + */ + id(): string + } + interface Job { + /** + * Expression returns the plain cron job schedule expression. + */ + expression(): string + } + interface Job { + /** + * Run runs the cron job function. + */ + run(): void + } + interface Job { + /** + * MarshalJSON implements [json.Marshaler] and export the current + * jobs data into valid JSON. + */ + marshalJSON(): string|Array + } +} + +namespace sql { + /** + * IsolationLevel is the transaction isolation level used in [TxOptions]. + */ + interface IsolationLevel extends Number{} + interface IsolationLevel { + /** + * String returns the name of the transaction isolation level. + */ + string(): string + } + /** + * DBStats contains database statistics. + */ + interface DBStats { + maxOpenConnections: number // Maximum number of open connections to the database. + /** + * Pool Status + */ + openConnections: number // The number of established connections both in use and idle. + inUse: number // The number of connections currently in use. + idle: number // The number of idle connections. + /** + * Counters + */ + waitCount: number // The total number of connections waited for. + waitDuration: time.Duration // The total time blocked waiting for a new connection. + maxIdleClosed: number // The total number of connections closed due to SetMaxIdleConns. + maxIdleTimeClosed: number // The total number of connections closed due to SetConnMaxIdleTime. + maxLifetimeClosed: number // The total number of connections closed due to SetConnMaxLifetime. + } + /** + * Conn represents a single database connection rather than a pool of database + * connections. Prefer running queries from [DB] unless there is a specific + * need for a continuous single database connection. + * + * A Conn must call [Conn.Close] to return the connection to the database pool + * and may do so concurrently with a running query. + * + * After a call to [Conn.Close], all operations on the + * connection fail with [ErrConnDone]. + */ + interface Conn { + } + interface Conn { + /** + * PingContext verifies the connection to the database is still alive. + */ + pingContext(ctx: context.Context): void + } + interface Conn { + /** + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Conn { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Conn { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * the [*Row.Scan] method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Conn { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface Conn { + /** + * Raw executes f exposing the underlying driver connection for the + * duration of f. The driverConn must not be used outside of f. + * + * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable + * until [Conn.Close] is called. + */ + raw(f: (driverConn: any) => void): void + } + interface Conn { + /** + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. + */ + beginTx(ctx: context.Context, opts: TxOptions): (Tx) + } + interface Conn { + /** + * Close returns the connection to the connection pool. + * All operations after a Close will return with [ErrConnDone]. + * Close is safe to call concurrently with other operations and will + * block until all other operations finish. It may be useful to first + * cancel any used context and then call close directly after. + */ + close(): void + } + /** + * ColumnType contains the name and type of a column. + */ + interface ColumnType { + } + interface ColumnType { + /** + * Name returns the name or alias of the column. + */ + name(): string + } + interface ColumnType { + /** + * Length returns the column type length for variable length column types such + * as text and binary field types. If the type length is unbounded the value will + * be [math.MaxInt64] (any database limits will still apply). + * If the column type is not variable length, such as an int, or if not supported + * by the driver ok is false. + */ + length(): [number, boolean] + } + interface ColumnType { + /** + * DecimalSize returns the scale and precision of a decimal type. + * If not applicable or if not supported ok is false. + */ + decimalSize(): [number, number, boolean] + } + interface ColumnType { + /** + * ScanType returns a Go type suitable for scanning into using [Rows.Scan]. + * If a driver does not support this property ScanType will return + * the type of an empty interface. + */ + scanType(): any + } + interface ColumnType { + /** + * Nullable reports whether the column may be null. + * If a driver does not support this property ok will be false. + */ + nullable(): [boolean, boolean] + } + interface ColumnType { + /** + * DatabaseTypeName returns the database system name of the column type. If an empty + * string is returned, then the driver type name is not supported. + * Consult your driver documentation for a list of driver data types. [ColumnType.Length] specifiers + * are not included. + * Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", + * "INT", and "BIGINT". + */ + databaseTypeName(): string + } + /** + * Row is the result of calling [DB.QueryRow] to select a single row. + */ + interface Row { + } + interface Row { + /** + * Scan copies the columns from the matched row into the values + * pointed at by dest. See the documentation on [Rows.Scan] for details. + * If more than one row matches the query, + * Scan uses the first row and discards the rest. If no row matches + * the query, Scan returns [ErrNoRows]. + */ + scan(...dest: any[]): void + } + interface Row { + /** + * Err provides a way for wrapping packages to check for + * query errors without calling [Row.Scan]. + * Err returns the error, if any, that was encountered while running the query. + * If this error is not nil, this error will also be returned from [Row.Scan]. + */ + err(): void + } +} + +namespace types { +} + +namespace search { +} + namespace bufio { /** * Reader implements buffering for an io.Reader object. @@ -21049,131 +21945,6 @@ namespace bufio { } } -namespace syscall { - /** - * SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux. - * See user_namespaces(7). - * - * Note that User Namespaces are not available on a number of popular Linux - * versions (due to security issues), or are available but subject to AppArmor - * restrictions like in Ubuntu 24.04. - */ - interface SysProcIDMap { - containerID: number // Container ID. - hostID: number // Host ID. - size: number // Size. - } - // @ts-ignore - import errorspkg = errors - /** - * Credential holds user and group identities to be assumed - * by a child process started by [StartProcess]. - */ - interface Credential { - uid: number // User ID. - gid: number // Group ID. - groups: Array // Supplementary group IDs. - noSetGroups: boolean // If true, don't set supplementary groups - } - // @ts-ignore - import runtimesyscall = syscall - /** - * A Signal is a number describing a process signal. - * It implements the [os.Signal] interface. - */ - interface Signal extends Number{} - interface Signal { - signal(): void - } - interface Signal { - string(): string - } -} - -namespace time { - /** - * A Month specifies a month of the year (January = 1, ...). - */ - interface Month extends Number{} - interface Month { - /** - * String returns the English name of the month ("January", "February", ...). - */ - string(): string - } - /** - * A Weekday specifies a day of the week (Sunday = 0, ...). - */ - interface Weekday extends Number{} - interface Weekday { - /** - * String returns the English name of the day ("Sunday", "Monday", ...). - */ - string(): string - } - /** - * A Location maps time instants to the zone in use at that time. - * Typically, the Location represents the collection of time offsets - * in use in a geographical area. For many Locations the time offset varies - * depending on whether daylight savings time is in use at the time instant. - * - * Location is used to provide a time zone in a printed Time value and for - * calculations involving intervals that may cross daylight savings time - * boundaries. - */ - interface Location { - } - interface Location { - /** - * String returns a descriptive name for the time zone information, - * corresponding to the name argument to [LoadLocation] or [FixedZone]. - */ - string(): string - } -} - -namespace fs { -} - -namespace context { -} - -namespace net { - /** - * Addr represents a network end point address. - * - * The two methods [Addr.Network] and [Addr.String] conventionally return strings - * that can be passed as the arguments to [Dial], but the exact form - * and meaning of the strings is up to the implementation. - */ - interface Addr { - [key:string]: any; - network(): string // name of the network (for example, "tcp", "udp") - string(): string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") - } - /** - * A Listener is a generic network listener for stream-oriented protocols. - * - * Multiple goroutines may invoke methods on a Listener simultaneously. - */ - interface Listener { - [key:string]: any; - /** - * Accept waits for and returns the next connection to the listener. - */ - accept(): Conn - /** - * Close closes the listener. - * Any blocked Accept operations will be unblocked and return errors. - */ - close(): void - /** - * Addr returns the listener's network address. - */ - addr(): Addr - } -} - /** * Package textproto implements generic support for text-based request/response * protocols in the style of HTTP, NNTP, and SMTP. @@ -21245,548 +22016,6 @@ namespace textproto { } } -namespace store { -} - -/** - * Package url parses URLs and implements query escaping. - */ -namespace url { - /** - * A URL represents a parsed URL (technically, a URI reference). - * - * The general form represented is: - * - * ``` - * [scheme:][//[userinfo@]host][/]path[?query][#fragment] - * ``` - * - * URLs that do not start with a slash after the scheme are interpreted as: - * - * ``` - * scheme:opaque[?query][#fragment] - * ``` - * - * The Host field contains the host and port subcomponents of the URL. - * When the port is present, it is separated from the host with a colon. - * When the host is an IPv6 address, it must be enclosed in square brackets: - * "[fe80::1]:80". The [net.JoinHostPort] function combines a host and port - * into a string suitable for the Host field, adding square brackets to - * the host when necessary. - * - * Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. - * A consequence is that it is impossible to tell which slashes in the Path were - * slashes in the raw URL and which were %2f. This distinction is rarely important, - * but when it is, the code should use the [URL.EscapedPath] method, which preserves - * the original encoding of Path. - * - * The RawPath field is an optional field which is only set when the default - * encoding of Path is different from the escaped path. See the EscapedPath method - * for more details. - * - * URL's String method uses the EscapedPath method to obtain the path. - */ - interface URL { - scheme: string - opaque: string // encoded opaque data - user?: Userinfo // username and password information - host: string // host or host:port (see Hostname and Port methods) - path: string // path (relative paths may omit leading slash) - rawPath: string // encoded path hint (see EscapedPath method) - omitHost: boolean // do not emit empty host (authority) - forceQuery: boolean // append a query ('?') even if RawQuery is empty - rawQuery: string // encoded query values, without '?' - fragment: string // fragment for references, without '#' - rawFragment: string // encoded fragment hint (see EscapedFragment method) - } - interface URL { - /** - * EscapedPath returns the escaped form of u.Path. - * In general there are multiple possible escaped forms of any path. - * EscapedPath returns u.RawPath when it is a valid escaping of u.Path. - * Otherwise EscapedPath ignores u.RawPath and computes an escaped - * form on its own. - * The [URL.String] and [URL.RequestURI] methods use EscapedPath to construct - * their results. - * In general, code should call EscapedPath instead of - * reading u.RawPath directly. - */ - escapedPath(): string - } - interface URL { - /** - * EscapedFragment returns the escaped form of u.Fragment. - * In general there are multiple possible escaped forms of any fragment. - * EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. - * Otherwise EscapedFragment ignores u.RawFragment and computes an escaped - * form on its own. - * The [URL.String] method uses EscapedFragment to construct its result. - * In general, code should call EscapedFragment instead of - * reading u.RawFragment directly. - */ - escapedFragment(): string - } - interface URL { - /** - * String reassembles the [URL] into a valid URL string. - * The general form of the result is one of: - * - * ``` - * scheme:opaque?query#fragment - * scheme://userinfo@host/path?query#fragment - * ``` - * - * If u.Opaque is non-empty, String uses the first form; - * otherwise it uses the second form. - * Any non-ASCII characters in host are escaped. - * To obtain the path, String uses u.EscapedPath(). - * - * In the second form, the following rules apply: - * ``` - * - if u.Scheme is empty, scheme: is omitted. - * - if u.User is nil, userinfo@ is omitted. - * - if u.Host is empty, host/ is omitted. - * - if u.Scheme and u.Host are empty and u.User is nil, - * the entire scheme://userinfo@host/ is omitted. - * - if u.Host is non-empty and u.Path begins with a /, - * the form host/path does not add its own /. - * - if u.RawQuery is empty, ?query is omitted. - * - if u.Fragment is empty, #fragment is omitted. - * ``` - */ - string(): string - } - interface URL { - /** - * Redacted is like [URL.String] but replaces any password with "xxxxx". - * Only the password in u.User is redacted. - */ - redacted(): string - } - /** - * Values maps a string key to a list of values. - * It is typically used for query parameters and form values. - * Unlike in the http.Header map, the keys in a Values map - * are case-sensitive. - */ - interface Values extends _TygojaDict{} - interface Values { - /** - * Get gets the first value associated with the given key. - * If there are no values associated with the key, Get returns - * the empty string. To access multiple values, use the map - * directly. - */ - get(key: string): string - } - interface Values { - /** - * Set sets the key to value. It replaces any existing - * values. - */ - set(key: string, value: string): void - } - interface Values { - /** - * Add adds the value to key. It appends to any existing - * values associated with key. - */ - add(key: string, value: string): void - } - interface Values { - /** - * Del deletes the values associated with key. - */ - del(key: string): void - } - interface Values { - /** - * Has checks whether a given key is set. - */ - has(key: string): boolean - } - interface Values { - /** - * Encode encodes the values into “URL encoded” form - * ("bar=baz&foo=quux") sorted by key. - */ - encode(): string - } - interface URL { - /** - * IsAbs reports whether the [URL] is absolute. - * Absolute means that it has a non-empty scheme. - */ - isAbs(): boolean - } - interface URL { - /** - * Parse parses a [URL] in the context of the receiver. The provided URL - * may be relative or absolute. Parse returns nil, err on parse - * failure, otherwise its return value is the same as [URL.ResolveReference]. - */ - parse(ref: string): (URL) - } - interface URL { - /** - * ResolveReference resolves a URI reference to an absolute URI from - * an absolute base URI u, per RFC 3986 Section 5.2. The URI reference - * may be relative or absolute. ResolveReference always returns a new - * [URL] instance, even if the returned URL is identical to either the - * base or reference. If ref is an absolute URL, then ResolveReference - * ignores base and returns a copy of ref. - */ - resolveReference(ref: URL): (URL) - } - interface URL { - /** - * Query parses RawQuery and returns the corresponding values. - * It silently discards malformed value pairs. - * To check errors use [ParseQuery]. - */ - query(): Values - } - interface URL { - /** - * RequestURI returns the encoded path?query or opaque?query - * string that would be used in an HTTP request for u. - */ - requestURI(): string - } - interface URL { - /** - * Hostname returns u.Host, stripping any valid port number if present. - * - * If the result is enclosed in square brackets, as literal IPv6 addresses are, - * the square brackets are removed from the result. - */ - hostname(): string - } - interface URL { - /** - * Port returns the port part of u.Host, without the leading colon. - * - * If u.Host doesn't contain a valid numeric port, Port returns an empty string. - */ - port(): string - } - interface URL { - marshalBinary(): string|Array - } - interface URL { - unmarshalBinary(text: string|Array): void - } - interface URL { - /** - * JoinPath returns a new [URL] with the provided path elements joined to - * any existing path and the resulting path cleaned of any ./ or ../ elements. - * Any sequences of multiple / characters will be reduced to a single /. - */ - joinPath(...elem: string[]): (URL) - } -} - -namespace types { -} - -namespace jwt { - /** - * NumericDate represents a JSON numeric date value, as referenced at - * https://datatracker.ietf.org/doc/html/rfc7519#section-2. - */ - type _speLYSq = time.Time - interface NumericDate extends _speLYSq { - } - interface NumericDate { - /** - * MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch - * represented in NumericDate to a byte array, using the precision specified in TimePrecision. - */ - marshalJSON(): string|Array - } - interface NumericDate { - /** - * UnmarshalJSON is an implementation of the json.RawMessage interface and - * deserializes a [NumericDate] from a JSON representation, i.e. a - * [json.Number]. This number represents an UNIX epoch with either integer or - * non-integer seconds. - */ - unmarshalJSON(b: string|Array): void - } - /** - * ClaimStrings is basically just a slice of strings, but it can be either - * serialized from a string array or just a string. This type is necessary, - * since the "aud" claim can either be a single string or an array. - */ - interface ClaimStrings extends Array{} - interface ClaimStrings { - unmarshalJSON(data: string|Array): void - } - interface ClaimStrings { - marshalJSON(): string|Array - } -} - -namespace subscriptions { -} - -namespace cobra { - interface PositionalArgs {(cmd: Command, args: Array): void } - // @ts-ignore - import flag = pflag - /** - * FParseErrWhitelist configures Flag parse errors to be ignored - */ - interface FParseErrWhitelist extends _TygojaAny{} - /** - * Group Structure to manage groups for commands - */ - interface Group { - id: string - title: string - } - /** - * CompletionOptions are the options to control shell completion - */ - interface CompletionOptions { - /** - * DisableDefaultCmd prevents Cobra from creating a default 'completion' command - */ - disableDefaultCmd: boolean - /** - * DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag - * for shells that support completion descriptions - */ - disableNoDescFlag: boolean - /** - * DisableDescriptions turns off all completion descriptions for shells - * that support them - */ - disableDescriptions: boolean - /** - * HiddenDefaultCmd makes the default 'completion' command hidden - */ - hiddenDefaultCmd: boolean - } - /** - * Completion is a string that can be used for completions - * - * two formats are supported: - * ``` - * - the completion choice - * - the completion choice with a textual description (separated by a TAB). - * ``` - * - * [CompletionWithDesc] can be used to create a completion string with a textual description. - * - * Note: Go type alias is used to provide a more descriptive name in the documentation, but any string can be used. - */ - interface Completion extends String{} - /** - * CompletionFunc is a function that provides completion results. - */ - interface CompletionFunc {(cmd: Command, args: Array, toComplete: string): [Array, ShellCompDirective] } -} - -namespace cron { - /** - * Job defines a single registered cron job. - */ - interface Job { - } - interface Job { - /** - * Id returns the cron job id. - */ - id(): string - } - interface Job { - /** - * Expression returns the plain cron job schedule expression. - */ - expression(): string - } - interface Job { - /** - * Run runs the cron job function. - */ - run(): void - } - interface Job { - /** - * MarshalJSON implements [json.Marshaler] and export the current - * jobs data into valid JSON. - */ - marshalJSON(): string|Array - } -} - -namespace slog { - /** - * An Attr is a key-value pair. - */ - interface Attr { - key: string - value: Value - } - interface Attr { - /** - * Equal reports whether a and b have equal keys and values. - */ - equal(b: Attr): boolean - } - interface Attr { - string(): string - } - /** - * A Handler handles log records produced by a Logger. - * - * A typical handler may print log records to standard error, - * or write them to a file or database, or perhaps augment them - * with additional attributes and pass them on to another handler. - * - * Any of the Handler's methods may be called concurrently with itself - * or with other methods. It is the responsibility of the Handler to - * manage this concurrency. - * - * Users of the slog package should not invoke Handler methods directly. - * They should use the methods of [Logger] instead. - */ - interface Handler { - [key:string]: any; - /** - * Enabled reports whether the handler handles records at the given level. - * The handler ignores records whose level is lower. - * It is called early, before any arguments are processed, - * to save effort if the log event should be discarded. - * If called from a Logger method, the first argument is the context - * passed to that method, or context.Background() if nil was passed - * or the method does not take a context. - * The context is passed so Enabled can use its values - * to make a decision. - */ - enabled(_arg0: context.Context, _arg1: Level): boolean - /** - * Handle handles the Record. - * It will only be called when Enabled returns true. - * The Context argument is as for Enabled. - * It is present solely to provide Handlers access to the context's values. - * Canceling the context should not affect record processing. - * (Among other things, log messages may be necessary to debug a - * cancellation-related problem.) - * - * Handle methods that produce output should observe the following rules: - * ``` - * - If r.Time is the zero time, ignore the time. - * - If r.PC is zero, ignore it. - * - Attr's values should be resolved. - * - If an Attr's key and value are both the zero value, ignore the Attr. - * This can be tested with attr.Equal(Attr{}). - * - If a group's key is empty, inline the group's Attrs. - * - If a group has no Attrs (even if it has a non-empty key), - * ignore it. - * ``` - */ - handle(_arg0: context.Context, _arg1: Record): void - /** - * WithAttrs returns a new Handler whose attributes consist of - * both the receiver's attributes and the arguments. - * The Handler owns the slice: it may retain, modify or discard it. - */ - withAttrs(attrs: Array): Handler - /** - * WithGroup returns a new Handler with the given group appended to - * the receiver's existing groups. - * The keys of all subsequent attributes, whether added by With or in a - * Record, should be qualified by the sequence of group names. - * - * How this qualification happens is up to the Handler, so long as - * this Handler's attribute keys differ from those of another Handler - * with a different sequence of group names. - * - * A Handler should treat WithGroup as starting a Group of Attrs that ends - * at the end of the log event. That is, - * - * ``` - * logger.WithGroup("s").LogAttrs(ctx, level, msg, slog.Int("a", 1), slog.Int("b", 2)) - * ``` - * - * should behave like - * - * ``` - * logger.LogAttrs(ctx, level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2))) - * ``` - * - * If the name is empty, WithGroup returns the receiver. - */ - withGroup(name: string): Handler - } - /** - * A Level is the importance or severity of a log event. - * The higher the level, the more important or severe the event. - */ - interface Level extends Number{} - interface Level { - /** - * String returns a name for the level. - * If the level has a name, then that name - * in uppercase is returned. - * If the level is between named values, then - * an integer is appended to the uppercased name. - * Examples: - * - * ``` - * LevelWarn.String() => "WARN" - * (LevelInfo+2).String() => "INFO+2" - * ``` - */ - string(): string - } - interface Level { - /** - * MarshalJSON implements [encoding/json.Marshaler] - * by quoting the output of [Level.String]. - */ - marshalJSON(): string|Array - } - interface Level { - /** - * UnmarshalJSON implements [encoding/json.Unmarshaler] - * It accepts any string produced by [Level.MarshalJSON], - * ignoring case. - * It also accepts numeric offsets that would result in a different string on - * output. For example, "Error-8" would marshal as "INFO". - */ - unmarshalJSON(data: string|Array): void - } - interface Level { - /** - * MarshalText implements [encoding.TextMarshaler] - * by calling [Level.String]. - */ - marshalText(): string|Array - } - interface Level { - /** - * UnmarshalText implements [encoding.TextUnmarshaler]. - * It accepts any string produced by [Level.MarshalText], - * ignoring case. - * It also accepts numeric offsets that would result in a different string on - * output. For example, "Error-8" would marshal as "INFO". - */ - unmarshalText(data: string|Array): void - } - interface Level { - /** - * Level returns the receiver. - * It implements [Leveler]. - */ - level(): Level - } - // @ts-ignore - import loginternal = internal -} - namespace multipart { interface Reader { /** @@ -21855,212 +22084,6 @@ namespace multipart { } } -namespace sql { - /** - * IsolationLevel is the transaction isolation level used in [TxOptions]. - */ - interface IsolationLevel extends Number{} - interface IsolationLevel { - /** - * String returns the name of the transaction isolation level. - */ - string(): string - } - /** - * DBStats contains database statistics. - */ - interface DBStats { - maxOpenConnections: number // Maximum number of open connections to the database. - /** - * Pool Status - */ - openConnections: number // The number of established connections both in use and idle. - inUse: number // The number of connections currently in use. - idle: number // The number of idle connections. - /** - * Counters - */ - waitCount: number // The total number of connections waited for. - waitDuration: time.Duration // The total time blocked waiting for a new connection. - maxIdleClosed: number // The total number of connections closed due to SetMaxIdleConns. - maxIdleTimeClosed: number // The total number of connections closed due to SetConnMaxIdleTime. - maxLifetimeClosed: number // The total number of connections closed due to SetConnMaxLifetime. - } - /** - * Conn represents a single database connection rather than a pool of database - * connections. Prefer running queries from [DB] unless there is a specific - * need for a continuous single database connection. - * - * A Conn must call [Conn.Close] to return the connection to the database pool - * and may do so concurrently with a running query. - * - * After a call to [Conn.Close], all operations on the - * connection fail with [ErrConnDone]. - */ - interface Conn { - } - interface Conn { - /** - * PingContext verifies the connection to the database is still alive. - */ - pingContext(ctx: context.Context): void - } - interface Conn { - /** - * ExecContext executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface Conn { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface Conn { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * the [*Row.Scan] method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface Conn { - /** - * PrepareContext creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface Conn { - /** - * Raw executes f exposing the underlying driver connection for the - * duration of f. The driverConn must not be used outside of f. - * - * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable - * until [Conn.Close] is called. - */ - raw(f: (driverConn: any) => void): void - } - interface Conn { - /** - * BeginTx starts a transaction. - * - * The provided context is used until the transaction is committed or rolled back. - * If the context is canceled, the sql package will roll back - * the transaction. [Tx.Commit] will return an error if the context provided to - * BeginTx is canceled. - * - * The provided [TxOptions] is optional and may be nil if defaults should be used. - * If a non-default isolation level is used that the driver doesn't support, - * an error will be returned. - */ - beginTx(ctx: context.Context, opts: TxOptions): (Tx) - } - interface Conn { - /** - * Close returns the connection to the connection pool. - * All operations after a Close will return with [ErrConnDone]. - * Close is safe to call concurrently with other operations and will - * block until all other operations finish. It may be useful to first - * cancel any used context and then call close directly after. - */ - close(): void - } - /** - * ColumnType contains the name and type of a column. - */ - interface ColumnType { - } - interface ColumnType { - /** - * Name returns the name or alias of the column. - */ - name(): string - } - interface ColumnType { - /** - * Length returns the column type length for variable length column types such - * as text and binary field types. If the type length is unbounded the value will - * be [math.MaxInt64] (any database limits will still apply). - * If the column type is not variable length, such as an int, or if not supported - * by the driver ok is false. - */ - length(): [number, boolean] - } - interface ColumnType { - /** - * DecimalSize returns the scale and precision of a decimal type. - * If not applicable or if not supported ok is false. - */ - decimalSize(): [number, number, boolean] - } - interface ColumnType { - /** - * ScanType returns a Go type suitable for scanning into using [Rows.Scan]. - * If a driver does not support this property ScanType will return - * the type of an empty interface. - */ - scanType(): any - } - interface ColumnType { - /** - * Nullable reports whether the column may be null. - * If a driver does not support this property ok will be false. - */ - nullable(): [boolean, boolean] - } - interface ColumnType { - /** - * DatabaseTypeName returns the database system name of the column type. If an empty - * string is returned, then the driver type name is not supported. - * Consult your driver documentation for a list of driver data types. [ColumnType.Length] specifiers - * are not included. - * Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", - * "INT", and "BIGINT". - */ - databaseTypeName(): string - } - /** - * Row is the result of calling [DB.QueryRow] to select a single row. - */ - interface Row { - } - interface Row { - /** - * Scan copies the columns from the matched row into the values - * pointed at by dest. See the documentation on [Rows.Scan] for details. - * If more than one row matches the query, - * Scan uses the first row and discards the rest. If no row matches - * the query, Scan returns [ErrNoRows]. - */ - scan(...dest: any[]): void - } - interface Row { - /** - * Err provides a way for wrapping packages to check for - * query errors without calling [Row.Scan]. - * Err returns the error, if any, that was encountered while running the query. - * If this error is not nil, this error will also be returned from [Row.Scan]. - */ - err(): void - } -} - -namespace search { -} - namespace http { /** * A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an @@ -22342,12 +22365,178 @@ namespace http { } } +namespace slog { + /** + * An Attr is a key-value pair. + */ + interface Attr { + key: string + value: Value + } + interface Attr { + /** + * Equal reports whether a and b have equal keys and values. + */ + equal(b: Attr): boolean + } + interface Attr { + string(): string + } + /** + * A Handler handles log records produced by a Logger. + * + * A typical handler may print log records to standard error, + * or write them to a file or database, or perhaps augment them + * with additional attributes and pass them on to another handler. + * + * Any of the Handler's methods may be called concurrently with itself + * or with other methods. It is the responsibility of the Handler to + * manage this concurrency. + * + * Users of the slog package should not invoke Handler methods directly. + * They should use the methods of [Logger] instead. + */ + interface Handler { + [key:string]: any; + /** + * Enabled reports whether the handler handles records at the given level. + * The handler ignores records whose level is lower. + * It is called early, before any arguments are processed, + * to save effort if the log event should be discarded. + * If called from a Logger method, the first argument is the context + * passed to that method, or context.Background() if nil was passed + * or the method does not take a context. + * The context is passed so Enabled can use its values + * to make a decision. + */ + enabled(_arg0: context.Context, _arg1: Level): boolean + /** + * Handle handles the Record. + * It will only be called when Enabled returns true. + * The Context argument is as for Enabled. + * It is present solely to provide Handlers access to the context's values. + * Canceling the context should not affect record processing. + * (Among other things, log messages may be necessary to debug a + * cancellation-related problem.) + * + * Handle methods that produce output should observe the following rules: + * ``` + * - If r.Time is the zero time, ignore the time. + * - If r.PC is zero, ignore it. + * - Attr's values should be resolved. + * - If an Attr's key and value are both the zero value, ignore the Attr. + * This can be tested with attr.Equal(Attr{}). + * - If a group's key is empty, inline the group's Attrs. + * - If a group has no Attrs (even if it has a non-empty key), + * ignore it. + * ``` + */ + handle(_arg0: context.Context, _arg1: Record): void + /** + * WithAttrs returns a new Handler whose attributes consist of + * both the receiver's attributes and the arguments. + * The Handler owns the slice: it may retain, modify or discard it. + */ + withAttrs(attrs: Array): Handler + /** + * WithGroup returns a new Handler with the given group appended to + * the receiver's existing groups. + * The keys of all subsequent attributes, whether added by With or in a + * Record, should be qualified by the sequence of group names. + * + * How this qualification happens is up to the Handler, so long as + * this Handler's attribute keys differ from those of another Handler + * with a different sequence of group names. + * + * A Handler should treat WithGroup as starting a Group of Attrs that ends + * at the end of the log event. That is, + * + * ``` + * logger.WithGroup("s").LogAttrs(ctx, level, msg, slog.Int("a", 1), slog.Int("b", 2)) + * ``` + * + * should behave like + * + * ``` + * logger.LogAttrs(ctx, level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2))) + * ``` + * + * If the name is empty, WithGroup returns the receiver. + */ + withGroup(name: string): Handler + } + /** + * A Level is the importance or severity of a log event. + * The higher the level, the more important or severe the event. + */ + interface Level extends Number{} + interface Level { + /** + * String returns a name for the level. + * If the level has a name, then that name + * in uppercase is returned. + * If the level is between named values, then + * an integer is appended to the uppercased name. + * Examples: + * + * ``` + * LevelWarn.String() => "WARN" + * (LevelInfo+2).String() => "INFO+2" + * ``` + */ + string(): string + } + interface Level { + /** + * MarshalJSON implements [encoding/json.Marshaler] + * by quoting the output of [Level.String]. + */ + marshalJSON(): string|Array + } + interface Level { + /** + * UnmarshalJSON implements [encoding/json.Unmarshaler] + * It accepts any string produced by [Level.MarshalJSON], + * ignoring case. + * It also accepts numeric offsets that would result in a different string on + * output. For example, "Error-8" would marshal as "INFO". + */ + unmarshalJSON(data: string|Array): void + } + interface Level { + /** + * MarshalText implements [encoding.TextMarshaler] + * by calling [Level.String]. + */ + marshalText(): string|Array + } + interface Level { + /** + * UnmarshalText implements [encoding.TextUnmarshaler]. + * It accepts any string produced by [Level.MarshalText], + * ignoring case. + * It also accepts numeric offsets that would result in a different string on + * output. For example, "Error-8" would marshal as "INFO". + */ + unmarshalText(data: string|Array): void + } + interface Level { + /** + * Level returns the receiver. + * It implements [Leveler]. + */ + level(): Level + } + // @ts-ignore + import loginternal = internal +} + namespace hook { /** * wrapped local Hook embedded struct to limit the public API surface. */ - type _sjppzfe = Hook - interface mainHook extends _sjppzfe { + type _sXenNmM = Hook + interface mainHook extends _sXenNmM { } } @@ -22467,6 +22656,64 @@ namespace oauth2 { } } +namespace cobra { + interface PositionalArgs {(cmd: Command, args: Array): void } + // @ts-ignore + import flag = pflag + /** + * FParseErrWhitelist configures Flag parse errors to be ignored + */ + interface FParseErrWhitelist extends _TygojaAny{} + /** + * Group Structure to manage groups for commands + */ + interface Group { + id: string + title: string + } + /** + * CompletionOptions are the options to control shell completion + */ + interface CompletionOptions { + /** + * DisableDefaultCmd prevents Cobra from creating a default 'completion' command + */ + disableDefaultCmd: boolean + /** + * DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag + * for shells that support completion descriptions + */ + disableNoDescFlag: boolean + /** + * DisableDescriptions turns off all completion descriptions for shells + * that support them + */ + disableDescriptions: boolean + /** + * HiddenDefaultCmd makes the default 'completion' command hidden + */ + hiddenDefaultCmd: boolean + } + /** + * Completion is a string that can be used for completions + * + * two formats are supported: + * ``` + * - the completion choice + * - the completion choice with a textual description (separated by a TAB). + * ``` + * + * [CompletionWithDesc] can be used to create a completion string with a textual description. + * + * Note: Go type alias is used to provide a more descriptive name in the documentation, but any string can be used. + */ + interface Completion extends String{} + /** + * CompletionFunc is a function that provides completion results. + */ + interface CompletionFunc {(cmd: Command, args: Array, toComplete: string): [Array, ShellCompDirective] } +} + namespace url { /** * The Userinfo type is an immutable encapsulation of username and @@ -22507,6 +22754,61 @@ namespace cobra { interface ShellCompDirective extends Number{} } +namespace multipart { + /** + * A Part represents a single part in a multipart body. + */ + interface Part { + /** + * The headers of the body, if any, with the keys canonicalized + * in the same fashion that the Go http.Request headers are. + * For example, "foo-bar" changes case to "Foo-Bar" + */ + header: textproto.MIMEHeader + } + interface Part { + /** + * FormName returns the name parameter if p has a Content-Disposition + * of type "form-data". Otherwise it returns the empty string. + */ + formName(): string + } + interface Part { + /** + * FileName returns the filename parameter of the [Part]'s Content-Disposition + * header. If not empty, the filename is passed through filepath.Base (which is + * platform dependent) before being returned. + */ + fileName(): string + } + interface Part { + /** + * Read reads the body of a part, after its headers and before the + * next part (if any) begins. + */ + read(d: string|Array): number + } + interface Part { + close(): void + } +} + +namespace http { + /** + * SameSite allows a server to define a cookie attribute making it impossible for + * the browser to send this cookie along with cross-site requests. The main + * goal is to mitigate the risk of cross-origin information leakage, and provide + * some protection against cross-site request forgery attacks. + * + * See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details. + */ + interface SameSite extends Number{} + // @ts-ignore + import mathrand = rand + // @ts-ignore + import urlpkg = url +} + namespace slog { // @ts-ignore import loginternal = internal @@ -22679,61 +22981,6 @@ namespace slog { } } -namespace multipart { - /** - * A Part represents a single part in a multipart body. - */ - interface Part { - /** - * The headers of the body, if any, with the keys canonicalized - * in the same fashion that the Go http.Request headers are. - * For example, "foo-bar" changes case to "Foo-Bar" - */ - header: textproto.MIMEHeader - } - interface Part { - /** - * FormName returns the name parameter if p has a Content-Disposition - * of type "form-data". Otherwise it returns the empty string. - */ - formName(): string - } - interface Part { - /** - * FileName returns the filename parameter of the [Part]'s Content-Disposition - * header. If not empty, the filename is passed through filepath.Base (which is - * platform dependent) before being returned. - */ - fileName(): string - } - interface Part { - /** - * Read reads the body of a part, after its headers and before the - * next part (if any) begins. - */ - read(d: string|Array): number - } - interface Part { - close(): void - } -} - -namespace http { - /** - * SameSite allows a server to define a cookie attribute making it impossible for - * the browser to send this cookie along with cross-site requests. The main - * goal is to mitigate the risk of cross-origin information leakage, and provide - * some protection against cross-site request forgery attacks. - * - * See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details. - */ - interface SameSite extends Number{} - // @ts-ignore - import mathrand = rand - // @ts-ignore - import urlpkg = url -} - namespace slog { // @ts-ignore import loginternal = internal diff --git a/tools/filesystem/filesystem.go b/tools/filesystem/filesystem.go index a2887ff6..4e4fe8b6 100644 --- a/tools/filesystem/filesystem.go +++ b/tools/filesystem/filesystem.go @@ -112,6 +112,8 @@ func (s *System) Attributes(fileKey string) (*blob.Attributes, error) { // NB! Make sure to call Close() on the file after you are done working with it. // // If the file doesn't exist returns ErrNotFound. +// +// @todo consider renaming to GetFileReader to avoid the confusion with filesystem.File func (s *System) GetFile(fileKey string) (*blob.Reader, error) { return s.bucket.NewReader(s.ctx, fileKey) } @@ -241,7 +243,8 @@ func (s *System) UploadMultipart(fh *multipart.FileHeader, fileKey string) error return err } - if _, err := w.ReadFrom(f); err != nil { + _, err = w.ReadFrom(f) + if err != nil { w.Close() return err }