diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06fe9287..8a79452a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## v0.37.0 (WIP)
+
+- @todo
+
+
## v0.36.9
- Updated the Discord `AuthUser.Name` field to use `global_name` ([#7603](https://github.com/pocketbase/pocketbase/pull/7603); thanks @HansHans135).
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a0db7aaa..e5cae793 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,17 +1,20 @@
# Contributing to PocketBase
-Thanks for taking the time to improve PocketBase!
+> [!IMPORTANT]
+> Due to recent LLM spam, PRs are temporary disabled and only existing collaborators can open a PR.
+> If you stumble on an problem that you want to fix, please consider instead opening an issue or discussion with link to your fork _(if not obvious - LLM contributions are not welcome)_.
+> This status may change in the future in case GitHub finally decide to do something about the constant spam, or when I find time to move the project somewhere else.
This document describes how to prepare a PR for a change in the main repository.
- [Prerequisites](#prerequisites)
- [Making changes in the Go code](#making-changes-in-the-go-code)
-- [Making changes in the Admin UI](#making-changes-in-the-admin-ui)
+- [Making changes in the Superuser UI](#making-changes-in-the-admin-ui)
## Prerequisites
- Go 1.25+ (for making changes in the Go code)
-- Node 18+ (for making changes in the Admin UI)
+- Node 24+ (for making changes in the Superuser UI)
If you haven't already, you can fork the main repository and clone your fork so that you can work locally:
@@ -34,7 +37,7 @@ So, let's assume that you already done some changes in the PocketBase Go code an
1. Navigate to `examples/base`
2. Run `go run main.go serve`
-This will start a web server on `http://localhost:8090` with the embedded prebuilt Admin UI from `ui/dist`. And that's it!
+This will start a web server on `http://localhost:8090` with the embedded prebuilt Superuser UI from `ui/dist`. And that's it!
**Before making a PR to the main repository, it is a good idea to:**
@@ -57,11 +60,11 @@ This will start a web server on `http://localhost:8090` with the embedded prebui
make lint
```
-## Making changes in the Admin UI
+## Making changes in the Superuser UI
-PocketBase Admin UI is a single-page application (SPA) built with Svelte and Vite.
+PocketBase Superuser UI is a single-page application (SPA) built with Svelte and Vite.
-To start the Admin UI:
+To start the Superuser UI:
1. Navigate to the `ui` project directory
2. Run `npm install` to install the node dependencies
@@ -70,13 +73,13 @@ To start the Admin UI:
npm run dev
```
-You could open the browser and access the running Admin UI at `http://localhost:3000`.
+You could open the browser and access the running Superuser UI at `http://localhost:5173`.
-Since the Admin UI is just a client-side application, you need to have the PocketBase backend server also running in the background (either manually running the `examples/base/main.go` or download a prebuilt executable).
+Since the Superuser UI is just a client-side application, you need to have the PocketBase backend server also running in the background (either manually running the `examples/base/main.go` or download a prebuilt executable).
> [!NOTE]
-> By default, the Admin UI is expecting the backend server to be started at `http://localhost:8090`, but you could change that by creating a new `ui/.env.development.local` file with `PB_BACKEND_URL = YOUR_ADDRESS` variable inside it.
+> By default, the Superuser UI is expecting the backend server to be started at `http://localhost:8090`, but you could change that by creating a new `ui/.env.development.local` file with `PB_BACKEND_URL = YOUR_ADDRESS` variable inside it.
-Every change you make in the Admin UI should be automatically reflected in the browser at `http://localhost:3000` without reloading the page.
+Every change you make in the Superuser UI should be automatically reflected in the browser at `http://localhost:5173` without reloading the page.
-Once you are done with your changes, you have to build the Admin UI with `npm run build`, so that it can be embedded in the go package. And that's it - you can make your PR to the main PocketBase repository.
+Once you are done with your changes, you have to build the Superuser UI with `npm run build`, so that it can be embedded in the go package. And that's it - you can make your PR to the main PocketBase repository.
diff --git a/README.md b/README.md
index 913dfcb3..b274c625 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
@@ -146,10 +146,13 @@ You could help continuing its development by:
- [Contribute to the source code](CONTRIBUTING.md)
- [Suggest new features and report issues](https://github.com/pocketbase/pocketbase/issues)
-PRs for new OAuth2 providers, bug fixes, code optimizations and documentation improvements are more than welcome.
-
-But please refrain creating PRs for _new features_ without previously discussing the implementation details.
+Please refrain creating PRs for _new features_ without previously discussing the implementation details.
PocketBase has a [roadmap](https://github.com/orgs/pocketbase/projects/2) and I try to work on issues in specific order and such PRs often come in out of nowhere and skew all initial planning with tedious back-and-forth communication.
Don't get upset if I close your PR, even if it is well executed and tested. This doesn't mean that it will never be merged.
Later we can always refer to it and/or take pieces of your implementation when the time comes to work on the issue (don't worry you'll be credited in the release notes).
+
+> [!IMPORTANT]
+> Due to recent LLM spam, PRs are temporary disabled and only existing collaborators can open a PR.
+> If you stumble on an problem that you want to fix, please consider instead opening an issue or discussion with link to your fork _(if not obvious - LLM contributions are not welcome)_.
+> This status may change in the future in case GitHub finally decide to do something about the constant spam, or when I find time to move the project somewhere else.
diff --git a/apis/base.go b/apis/base.go
index 750b4d0b..c57075d4 100644
--- a/apis/base.go
+++ b/apis/base.go
@@ -15,7 +15,7 @@ import (
// StaticWildcardParam is the name of Static handler wildcard parameter.
const StaticWildcardParam = "path"
-// NewRouter returns a new router instance loaded with the default app middlewares and api routes.
+// NewRouter returns a new router instance loaded with the default app middlewares and routes.
func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) {
pbRouter := router.NewRouter(func(w http.ResponseWriter, r *http.Request) (*core.RequestEvent, router.EventCleanupFunc) {
event := new(core.RequestEvent)
@@ -34,6 +34,7 @@ func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) {
pbRouter.Bind(securityHeaders())
pbRouter.Bind(BodyLimit(DefaultMaxBodySize))
+ // API routes
apiGroup := pbRouter.Group("/api")
bindSettingsApi(app, apiGroup)
bindCollectionApi(app, apiGroup)
@@ -47,6 +48,9 @@ func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) {
bindRealtimeApi(app, apiGroup)
bindHealthApi(app, apiGroup)
+ // UI routes
+ bindUIExtensions(app)
+
return pbRouter, nil
}
diff --git a/apis/collection.go b/apis/collection.go
index baa24fe7..cfea38ff 100644
--- a/apis/collection.go
+++ b/apis/collection.go
@@ -3,10 +3,12 @@ package apis
import (
"errors"
"net/http"
+ "slices"
"strings"
validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tools/auth"
"github.com/pocketbase/pocketbase/tools/router"
"github.com/pocketbase/pocketbase/tools/search"
"github.com/pocketbase/pocketbase/tools/security"
@@ -23,6 +25,10 @@ func bindCollectionApi(app core.App, rg *router.RouterGroup[*core.RequestEvent])
subGroup.DELETE("/{collection}/truncate", collectionTruncate)
subGroup.PUT("/import", collectionsImport)
subGroup.GET("/meta/scaffolds", collectionScaffolds)
+
+ // @todo experimental
+ subGroup.GET("/meta/oauth2-providers", collectionListOAuth2Providers)
+ subGroup.POST("/meta/dry-run-view", collectionDryRunView)
}
func collectionsList(e *core.RequestEvent) error {
@@ -207,3 +213,84 @@ func collectionScaffolds(e *core.RequestEvent) error {
return e.JSON(http.StatusOK, collections)
}
+
+type providerListItem struct {
+ order int
+
+ Name string `json:"name"`
+ DisplayName string `json:"displayName"`
+ Logo string `json:"logo"`
+}
+
+func collectionListOAuth2Providers(e *core.RequestEvent) error {
+ providers := make([]*providerListItem, 0, len(auth.Providers))
+
+ for name, factory := range auth.Providers {
+ p := factory()
+
+ providers = append(providers, &providerListItem{
+ order: p.Order(),
+ Name: name,
+ DisplayName: p.DisplayName(),
+ Logo: p.Logo(),
+ })
+ }
+
+ slices.SortStableFunc(providers, func(a, b *providerListItem) int {
+ // sort by order
+ if a.order < b.order {
+ return -1
+ }
+ if a.order > b.order {
+ return 1
+ }
+
+ // fallback sort by name
+ if a.Name < b.Name {
+ return -1
+ }
+ if a.Name > b.Name {
+ return 1
+ }
+
+ return 0
+ })
+
+ return e.JSON(http.StatusOK, providers)
+}
+
+func collectionDryRunView(e *core.RequestEvent) error {
+ // extra precaution in case reused in custom route group
+ if !e.HasSuperuserAuth() {
+ return e.ForbiddenError("", nil)
+ }
+
+ form := dryRunViewForm{}
+
+ err := e.BindBody(&form)
+ if err != nil {
+ return firstApiError(err, e.BadRequestError("An error occurred while loading the submitted data.", err))
+ }
+
+ err = form.validate()
+ if err != nil {
+ return firstApiError(err, e.BadRequestError("An error occurred while validating the submitted data.", err))
+ }
+
+ result, err := e.App.DryRunView(form.Query, 10)
+ if err != nil {
+ return firstApiError(err, e.BadRequestError("Invalid view query. Raw error: \n"+err.Error(), nil))
+ }
+
+ return e.JSON(http.StatusOK, result)
+}
+
+type dryRunViewForm struct {
+ Query string `form:"query" json:"query"`
+}
+
+func (form *dryRunViewForm) validate() error {
+ return validation.ValidateStruct(form,
+ validation.Field(&form.Query, validation.Required, validation.Length(0, 5000)),
+ )
+}
diff --git a/apis/collection_test.go b/apis/collection_test.go
index 8d74f750..27051826 100644
--- a/apis/collection_test.go
+++ b/apis/collection_test.go
@@ -536,7 +536,7 @@ func TestCollectionCreate(t *testing.T) {
`"type":"base"`,
`"system":false`,
// ensures that id field was prepended
- `"fields":[{"autogeneratePattern":"[a-z0-9]{15}","hidden":false,"id":"text3208210256","max":15,"min":15,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"},{"autogeneratePattern":"","hidden":false,"id":"12345789","max":0,"min":0,"name":"test","pattern":"","presentable":false,"primaryKey":false,"required":false,"system":false,"type":"text"}]`,
+ `"fields":[{"autogeneratePattern":"[a-z0-9]{15}","help":"","hidden":false,"id":"text3208210256","max":15,"min":15,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"},{"autogeneratePattern":"","help":"","hidden":false,"id":"12345789","max":0,"min":0,"name":"test","pattern":"","presentable":false,"primaryKey":false,"required":false,"system":false,"type":"text"}]`,
},
ExpectedEvents: map[string]int{
"*": 0,
@@ -585,7 +585,7 @@ func TestCollectionCreate(t *testing.T) {
`"name":"verified"`,
`"duration":123`,
// should overwrite the user required option but keep the min value
- `{"autogeneratePattern":"","hidden":true,"id":"text2504183744","max":0,"min":10,"name":"tokenKey","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":true,"type":"text"}`,
+ `{"autogeneratePattern":"","help":"","hidden":true,"id":"text2504183744","max":0,"min":10,"name":"tokenKey","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":true,"type":"text"}`,
},
NotExpectedContent: []string{
`"secret":"`,
@@ -751,7 +751,7 @@ func TestCollectionCreate(t *testing.T) {
"name":"new",
"type":"view",
"fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}],
- "viewQuery":"invalid"
+ "viewQuery":"select '123' as abc"
}`),
Headers: map[string]string{
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
@@ -780,7 +780,7 @@ func TestCollectionCreate(t *testing.T) {
"name":"new",
"type":"view",
"fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}],
- "viewQuery": "select 1 as id from ` + core.CollectionNameSuperusers + `"
+ "viewQuery": "select 1 as id from ` + core.CollectionNameSuperusers + ` limit 1"
}`),
Headers: map[string]string{
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
@@ -789,7 +789,7 @@ func TestCollectionCreate(t *testing.T) {
ExpectedContent: []string{
`"name":"new"`,
`"type":"view"`,
- `"fields":[{"autogeneratePattern":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`,
+ `"fields":[{"autogeneratePattern":"","help":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`,
},
ExpectedEvents: map[string]int{
"*": 0,
@@ -1262,7 +1262,7 @@ func TestCollectionUpdate(t *testing.T) {
Body: strings.NewReader(`{
"name":"view2_update",
"fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}],
- "viewQuery": "select 2 as id, created, updated, email from ` + core.CollectionNameSuperusers + `"
+ "viewQuery": "select 2 as id, created, updated, email from ` + core.CollectionNameSuperusers + ` limit 1"
}`),
Headers: map[string]string{
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
@@ -1584,3 +1584,187 @@ func TestCollectionTruncate(t *testing.T) {
scenario.Test(t)
}
}
+
+func TestCollectionOAuth2Providers(t *testing.T) {
+ t.Parallel()
+
+ scenarios := []tests.ApiScenario{
+ {
+ Name: "unauthorized",
+ Method: http.MethodGet,
+ URL: "/api/collections/meta/oauth2-providers",
+ ExpectedStatus: 401,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "authorized as regular user",
+ Method: http.MethodGet,
+ URL: "/api/collections/meta/oauth2-providers",
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
+ },
+ ExpectedStatus: 403,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "authorized as superuser",
+ Method: http.MethodGet,
+ URL: "/api/collections/meta/oauth2-providers",
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 200,
+ ExpectedContent: []string{
+ `{"name":"oidc3","displayName":"OIDC","logo":"\u003csvg`,
+ },
+ NotExpectedContent: []string{
+ `"order":`,
+ `"pkce":`,
+ `"scopes":`,
+ `"authURL":`,
+ `"tokenURL":`,
+ `"userInfoURL":`,
+ },
+ },
+ }
+
+ for _, scenario := range scenarios {
+ scenario.Test(t)
+ }
+}
+
+func TestCollectionTestView(t *testing.T) {
+ t.Parallel()
+
+ scenarios := []tests.ApiScenario{
+ {
+ Name: "unauthorized",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"select 1 as id"}`),
+ ExpectedStatus: 401,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "authorized as regular user",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"select 1 as id"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
+ },
+ ExpectedStatus: 403,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "authorized as superuser",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"select 1 as id"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 200,
+ ExpectedContent: []string{
+ `"fields":[{`,
+ `"name":"id"`,
+ `"type":"text"`,
+ `"sample":[{`,
+ `"id":"1"`,
+ },
+ },
+ {
+ Name: "empty query",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":""}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 400,
+ ExpectedContent: []string{
+ `"data":{"query":`,
+ },
+ },
+ {
+ Name: "query length beyond validator limit",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"` + strings.Repeat("a", 5001) + `"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 400,
+ ExpectedContent: []string{
+ `"data":{"query":`,
+ },
+ },
+ {
+ Name: "query with length equal to the validator limit",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"select 1 as id` + strings.Repeat(" ", 4986) + `"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 200,
+ ExpectedContent: []string{
+ `"fields":[{`,
+ `"name":"id"`,
+ `"type":"text"`,
+ `"sample":[`,
+ `"id":"1"`,
+ },
+ },
+ {
+ Name: "missing ids sample",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"(select 1 as id union select '' as id)"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 400,
+ ExpectedContent: []string{
+ `"data":{}`,
+ `Raw error:`,
+ },
+ },
+ {
+ Name: "duplicated ids sample",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"(select 1 as id union all select 1 as id)"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 400,
+ ExpectedContent: []string{
+ `"data":{}`,
+ `Raw error:`,
+ },
+ },
+ {
+ Name: "write query",
+ Method: http.MethodPost,
+ URL: "/api/collections/meta/dry-run-view",
+ Body: strings.NewReader(`{"query":"CREATE TABLE t1(x INT)"}`),
+ Headers: map[string]string{
+ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY",
+ },
+ ExpectedStatus: 400,
+ ExpectedContent: []string{
+ `"data":{}`,
+ `Raw error:`,
+ },
+ },
+ }
+
+ for _, scenario := range scenarios {
+ scenario.Test(t)
+ }
+}
diff --git a/apis/extensions.go b/apis/extensions.go
new file mode 100644
index 00000000..b230bce7
--- /dev/null
+++ b/apis/extensions.go
@@ -0,0 +1,94 @@
+package apis
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "log/slog"
+ "os"
+
+ "github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tools/hook"
+ "github.com/pocketbase/pocketbase/ui"
+)
+
+// bindUIExtensions binds the superuser UI extensions routes to the ServeEvent.Router.
+//
+// This method does nothing if the superuser UI is not bundled (aka. build with "no_ui" tag),
+func bindUIExtensions(app core.App) {
+ if ui.DistDirFS == nil {
+ return
+ }
+
+ app.OnServe().Bind(&hook.Handler[*core.ServeEvent]{
+ Priority: 9999, // execute as latest as possible
+ Func: func(se *core.ServeEvent) error {
+ uiGroup := se.Router.Group("/_").
+ BindFunc(func(e *core.RequestEvent) error {
+ if !e.App.IsDev() && e.Response.Header().Get("Cache-Control") == "" {
+ e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400")
+ }
+
+ if e.Response.Header().Get("Content-Security-Policy") == "" {
+ e.Response.Header().Set("Content-Security-Policy", defaultCSP)
+ }
+
+ return e.Next()
+ }).
+ Bind(Gzip())
+
+ // register static extension routes
+ for _, ext := range se.UIExtensions {
+ if ext.Name == "" || ext.FS == nil {
+ se.App.Logger().Debug("Invalid UI extension configuration", slog.Any("extension", ext))
+ continue
+ }
+
+ uiGroup.GET("/extensions/"+ext.Name+"/{path...}", Static(ext.FS, false))
+ }
+
+ // combine all extensions main.js in one file
+ //
+ // note: don't cache in memory to allow previewing changes without restart
+ uiGroup.GET("/extensions.js", func(re *core.RequestEvent) error {
+ buf := new(bytes.Buffer)
+
+ for _, ext := range se.UIExtensions {
+ err := copyExtensionMainjs(buf, ext)
+ if err != nil {
+ return re.InternalServerError("An error occurred while generating the main.js extension file", err)
+ }
+ }
+
+ return re.Stream(200, "text/javascript", buf)
+ }).Bind(SkipSuccessActivityLog())
+
+ return se.Next()
+ },
+ })
+}
+
+func copyExtensionMainjs(buf *bytes.Buffer, ext core.UIExtension) error {
+ f, err := ext.FS.Open("main.js")
+ if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ return nil // nothing to copy
+ }
+
+ return fmt.Errorf("[UI extension %q] main.js open error: %w", ext.Name, err)
+ }
+ defer f.Close()
+
+ // wrap in a self-executing function to avoid scope and concatenation issues
+ _, _ = buf.WriteString("(function(){")
+
+ _, err = io.Copy(buf, f)
+ if err != nil {
+ return fmt.Errorf("[UI extension %q] main.js copy error: %w", ext.Name, err)
+ }
+
+ _, _ = buf.WriteString("})();")
+
+ return nil
+}
diff --git a/apis/extensions_test.go b/apis/extensions_test.go
new file mode 100644
index 00000000..b292a2d3
--- /dev/null
+++ b/apis/extensions_test.go
@@ -0,0 +1,177 @@
+package apis_test
+
+import (
+ "net/http"
+ "testing"
+ "testing/fstest"
+
+ "github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tests"
+ "github.com/pocketbase/pocketbase/ui"
+)
+
+// note: don't run in parallel to avoid conflicts with the ui.DistDirFS nil test
+func TestUIExtensions_Mainjs(t *testing.T) {
+ successAfterTestFunc := func(t testing.TB, app *tests.TestApp, res *http.Response) {
+ expected := "text/javascript"
+ if ct := res.Header.Get("content-type"); ct != expected {
+ t.Fatalf("Expected response Content-Type %q, got %q", expected, ct)
+ }
+ }
+
+ oldDistDirFS := ui.DistDirFS
+
+ scenarios := []tests.ApiScenario{
+ {
+ Name: "disabled UI",
+ Method: http.MethodGet,
+ URL: "/_/extensions.js",
+ TestAppFactory: func(t testing.TB) *tests.TestApp {
+ app, err := tests.NewTestApp()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // simulate no_ui tag (needs to be cleared before the router is initialized)
+ ui.DistDirFS = nil
+
+ return app
+ },
+ AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
+ ui.DistDirFS = oldDistDirFS
+ },
+ ExpectedStatus: 404,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "no extensions",
+ Method: http.MethodGet,
+ URL: "/_/extensions.js",
+ AfterTestFunc: successAfterTestFunc,
+ ExpectedStatus: 200,
+ ExpectedContent: []string{},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "with extensions",
+ Method: http.MethodGet,
+ URL: "/_/extensions.js",
+ TestAppFactory: func(t testing.TB) *tests.TestApp {
+ app, err := tests.NewTestApp()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ app.OnServe().BindFunc(func(e *core.ServeEvent) error {
+ e.UIExtensions = createTestExtensions()
+ return e.Next()
+ })
+
+ return app
+ },
+ AfterTestFunc: successAfterTestFunc,
+ ExpectedStatus: 200,
+ ExpectedContent: []string{"(function(){ext1_main})();(function(){ext3_main})();"},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ }
+
+ for _, scenario := range scenarios {
+ scenario.Test(t)
+ }
+}
+
+// note: don't run in parallel to avoid conflicts with the ui.DistDirFS nil test
+func TestUIExtensions_Files(t *testing.T) {
+ testAppFactory := func(t testing.TB) *tests.TestApp {
+ app, err := tests.NewTestApp()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ app.OnServe().BindFunc(func(e *core.ServeEvent) error {
+ e.UIExtensions = createTestExtensions()
+ return e.Next()
+ })
+
+ return app
+ }
+
+ scenarios := []tests.ApiScenario{
+ {
+ Name: "no extensions",
+ Method: http.MethodGet,
+ URL: "/_/extensions/ext1/test.txt",
+ ExpectedStatus: 404,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "with missing extension file",
+ Method: http.MethodGet,
+ URL: "/_/extensions/ext1/missing",
+ TestAppFactory: testAppFactory,
+ ExpectedStatus: 404,
+ ExpectedContent: []string{`"data":{}`},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "with existing extension file (ext1)",
+ Method: http.MethodGet,
+ URL: "/_/extensions/ext1/test.txt",
+ TestAppFactory: testAppFactory,
+ ExpectedStatus: 200,
+ ExpectedContent: []string{"ext1_txt"},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ {
+ Name: "with existing extension file (extension name escape)",
+ Method: http.MethodGet,
+ URL: "/_/extensions/ext3%20with%20spaces/test.txt",
+ TestAppFactory: testAppFactory,
+ ExpectedStatus: 200,
+ ExpectedContent: []string{"ext3_txt"},
+ ExpectedEvents: map[string]int{"*": 0},
+ },
+ }
+
+ for _, scenario := range scenarios {
+ scenario.Test(t)
+ }
+}
+
+func createTestExtensions() []core.UIExtension {
+ return []core.UIExtension{
+ {
+ Name: "ext1",
+ FS: fstest.MapFS{
+ "main.js": &fstest.MapFile{
+ Data: []byte("ext1_main"),
+ },
+ "test.txt": &fstest.MapFile{
+ Data: []byte("ext1_txt"),
+ },
+ },
+ },
+ {
+ Name: "ext2",
+ FS: fstest.MapFS{
+ "test.txt": &fstest.MapFile{
+ Data: []byte("ext2_txt"),
+ },
+ },
+ },
+ {
+ Name: "ext3 with spaces",
+ FS: fstest.MapFS{
+ "main.js": &fstest.MapFile{
+ Data: []byte("ext3_main"),
+ },
+ "test.txt": &fstest.MapFile{
+ Data: []byte("ext3_txt"),
+ },
+ },
+ },
+ }
+}
diff --git a/apis/health.go b/apis/health.go
index 5b13b429..aa438070 100644
--- a/apis/health.go
+++ b/apis/health.go
@@ -25,6 +25,7 @@ func healthCheck(e *core.RequestEvent) error {
Message: "API is healthy.",
}
+ // @todo evaluate whether it is worth removing the extra info from the health endpoint
if e.HasSuperuserAuth() {
resp.Data = make(map[string]any, 3)
resp.Data["canBackup"] = !e.App.Store().Has(core.StoreKeyActiveBackup)
diff --git a/apis/installer.go b/apis/installer.go
index 72405808..7085525f 100644
--- a/apis/installer.go
+++ b/apis/installer.go
@@ -12,6 +12,7 @@ import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/osutils"
+ "github.com/pocketbase/pocketbase/ui"
)
// DefaultInstallerFunc is the default PocketBase installer function.
@@ -22,13 +23,18 @@ import (
//
// See https://github.com/pocketbase/pocketbase/discussions/5814.
func DefaultInstallerFunc(app core.App, systemSuperuser *core.Record, baseURL string) error {
+ if ui.DistDirFS == nil {
+ color.Magenta("You can create your first superuser by running: %s superuser upsert EMAIL PASS", executablePath())
+ return nil
+ }
+
token, err := systemSuperuser.NewStaticAuthToken(30 * time.Minute)
if err != nil {
return err
}
// launch url (ignore errors and always print a help text as fallback)
- url := fmt.Sprintf("%s/_/#/pbinstal/%s", strings.TrimRight(baseURL, "/"), token)
+ url := fmt.Sprintf("%s/_/#/pbinstall/%s", strings.TrimRight(baseURL, "/"), token)
_ = osutils.LaunchURL(url)
color.Magenta("\n(!) Launch the URL below in the browser if it hasn't been open already to create your first superuser account:")
color.New(color.Bold).Add(color.FgCyan).Println(url)
diff --git a/apis/middlewares_body_limit.go b/apis/middlewares_body_limit.go
index d2a16e0b..b02f0f65 100644
--- a/apis/middlewares_body_limit.go
+++ b/apis/middlewares_body_limit.go
@@ -11,7 +11,7 @@ import (
var ErrRequestEntityTooLarge = router.NewApiError(http.StatusRequestEntityTooLarge, "Request entity too large", nil)
-const DefaultMaxBodySize int64 = 32 << 20
+const DefaultMaxBodySize int64 = 32 << 20 // @todo consider replacing with router.DefaultMaxMemory
const (
DefaultBodyLimitMiddlewareId = "pbBodyLimit"
diff --git a/apis/record_auth_methods.go b/apis/record_auth_methods.go
index df39d662..1cb59cfd 100644
--- a/apis/record_auth_methods.go
+++ b/apis/record_auth_methods.go
@@ -34,6 +34,7 @@ type oauth2Response struct {
type providerInfo struct {
Name string `json:"name"`
DisplayName string `json:"displayName"`
+ Logo string `json:"logo"`
State string `json:"state"`
AuthURL string `json:"authURL"`
@@ -68,7 +69,14 @@ func (amr *authMethodsResponse) fillLegacyFields() {
amr.UsernamePassword = amr.Password.Enabled && slices.Contains(amr.Password.IdentityFields, "username")
if amr.OAuth2.Enabled {
- amr.AuthProviders = amr.OAuth2.Providers
+ // clone without the logo
+ legacyProviders := make([]providerInfo, len(amr.OAuth2.Providers))
+ for i, p := range amr.OAuth2.Providers {
+ legacyProviders[i] = p
+ legacyProviders[i].Logo = ""
+ }
+
+ amr.AuthProviders = legacyProviders
}
}
@@ -128,6 +136,7 @@ func recordAuthMethods(e *core.RequestEvent) error {
info := providerInfo{
Name: config.Name,
DisplayName: provider.DisplayName(),
+ Logo: provider.Logo(),
State: security.RandomString(30),
}
diff --git a/apis/record_auth_methods_test.go b/apis/record_auth_methods_test.go
index ec624681..0ea1bd67 100644
--- a/apis/record_auth_methods_test.go
+++ b/apis/record_auth_methods_test.go
@@ -54,6 +54,8 @@ func TestRecordAuthMethodsList(t *testing.T) {
`"providers":[{`,
`"name":"google"`,
`"name":"gitlab"`,
+ `"logo":"\u003csvg`,
+ `"logo":""`, // for the legacy fields
`"state":`,
`"displayName":`,
`"codeVerifier":`,
diff --git a/apis/record_auth_with_oauth2_redirect.go b/apis/record_auth_with_oauth2_redirect.go
index c4ac4583..c2c73c7d 100644
--- a/apis/record_auth_with_oauth2_redirect.go
+++ b/apis/record_auth_with_oauth2_redirect.go
@@ -9,6 +9,7 @@ import (
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/subscriptions"
+ "github.com/pocketbase/pocketbase/ui"
)
const (
@@ -28,17 +29,12 @@ type oauth2RedirectData struct {
}
func oauth2SubscriptionRedirect(e *core.RequestEvent) error {
- redirectStatusCode := http.StatusTemporaryRedirect
- if e.Request.Method != http.MethodGet {
- redirectStatusCode = http.StatusSeeOther
- }
-
data := oauth2RedirectData{}
if e.Request.Method == http.MethodPost {
if err := e.BindBody(&data); err != nil {
e.App.Logger().Debug("Failed to read OAuth2 redirect data", "error", err)
- return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath)
+ return failureRedirect(e)
}
} else {
query := e.Request.URL.Query()
@@ -49,13 +45,13 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error {
if data.State == "" {
e.App.Logger().Debug("Missing OAuth2 state parameter")
- return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath)
+ return failureRedirect(e)
}
client, err := e.App.SubscriptionsBroker().ClientById(data.State)
if err != nil || client.IsDiscarded() || !client.HasSubscription(oauth2SubscriptionTopic) {
e.App.Logger().Debug("Missing or invalid OAuth2 subscription client", "error", err, "clientId", data.State)
- return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath)
+ return failureRedirect(e)
}
defer client.Unsubscribe(oauth2SubscriptionTopic)
@@ -76,7 +72,7 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error {
encodedData, err := json.Marshal(data)
if err != nil {
e.App.Logger().Debug("Failed to marshalize OAuth2 redirect data", "error", err)
- return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath)
+ return failureRedirect(e)
}
msg := subscriptions.Message{
@@ -88,10 +84,36 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error {
if data.Error != "" || data.Code == "" {
e.App.Logger().Debug("Failed OAuth2 redirect due to an error or missing code parameter", "error", data.Error, "clientId", data.State)
- return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath)
+ return failureRedirect(e)
}
- return e.Redirect(redirectStatusCode, oauth2RedirectSuccessPath)
+ return successRedirect(e)
+}
+
+func redirectStatusCode(e *core.RequestEvent) int {
+ if e.Request.Method != http.MethodGet {
+ return http.StatusSeeOther
+ }
+
+ return http.StatusTemporaryRedirect
+}
+
+func failureRedirect(e *core.RequestEvent) error {
+ // fallback if UI is not bundled
+ if ui.DistDirFS == nil {
+ return e.String(http.StatusOK, "Failed to authenticate. You can close this window and go back to the app to try again.")
+ }
+
+ return e.Redirect(redirectStatusCode(e), oauth2RedirectFailurePath)
+}
+
+func successRedirect(e *core.RequestEvent) error {
+ // fallback if UI is not bundled
+ if ui.DistDirFS == nil {
+ return e.HTML(http.StatusOK, "Auth completed. You can close this window and go back to the app.")
+ }
+
+ return e.Redirect(redirectStatusCode(e), oauth2RedirectSuccessPath)
}
// parseAndStoreAppleRedirectName extracts the first and last name
diff --git a/apis/serve.go b/apis/serve.go
index d2af0c76..193d103c 100644
--- a/apis/serve.go
+++ b/apis/serve.go
@@ -22,6 +22,8 @@ import (
"golang.org/x/crypto/acme/autocert"
)
+const defaultCSP = "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' http://127.0.0.1:* https://tile.openstreetmap.org data: blob:; connect-src 'self' http://127.0.0.1:* https://nominatim.openstreetmap.org; script-src 'self' http://127.0.0.1:*; frame-src 'none'"
+
// ServeConfig defines a configuration struct for apis.Serve().
type ServeConfig struct {
// ShowStartBanner indicates whether to show or hide the server start console message.
@@ -77,21 +79,25 @@ func Serve(app core.App, config ServeConfig) error {
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
}))
- pbRouter.GET("/_/{path...}", Static(ui.DistDirFS, false)).
- BindFunc(func(e *core.RequestEvent) error {
- // ignore root path
- if e.Request.PathValue(StaticWildcardParam) != "" {
- e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400")
- }
+ // @todo consider moving in base
+ if ui.DistDirFS != nil {
+ pbRouter.GET("/_/{path...}", Static(ui.DistDirFS, false)).
+ BindFunc(func(e *core.RequestEvent) error {
+ if !e.App.IsDev() &&
+ // exclude root path
+ e.Request.PathValue(StaticWildcardParam) != "" &&
+ e.Response.Header().Get("Cache-Control") == "" {
+ e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400")
+ }
- // add a default CSP
- if e.Response.Header().Get("Content-Security-Policy") == "" {
- e.Response.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' http://127.0.0.1:* https://tile.openstreetmap.org data: blob:; connect-src 'self' http://127.0.0.1:* https://nominatim.openstreetmap.org; script-src 'self' 'sha256-GRUzBA7PzKYug7pqxv5rJaec5bwDCw1Vo6/IXwvD3Tc='")
- }
+ if e.Response.Header().Get("Content-Security-Policy") == "" {
+ e.Response.Header().Set("Content-Security-Policy", defaultCSP)
+ }
- return e.Next()
- }).
- Bind(Gzip())
+ return e.Next()
+ }).
+ Bind(Gzip())
+ }
// start http server
// ---
@@ -279,8 +285,12 @@ func Serve(app core.App, config ServeConfig) error {
)
regular := color.New()
- regular.Printf("├─ REST API: %s\n", color.CyanString("%s/api/", baseURL))
- regular.Printf("└─ Dashboard: %s\n", color.CyanString("%s/_/", baseURL))
+ if ui.DistDirFS == nil {
+ regular.Printf("└─ REST API: %s\n", color.CyanString("%s/api/", baseURL))
+ } else {
+ regular.Printf("├─ REST API: %s\n", color.CyanString("%s/api/", baseURL))
+ regular.Printf("└─ Dashboard: %s\n", color.CyanString("%s/_/", baseURL))
+ }
}
var serveErr error
diff --git a/apis/settings.go b/apis/settings.go
index d6d609cd..c0522d0b 100644
--- a/apis/settings.go
+++ b/apis/settings.go
@@ -16,6 +16,8 @@ func bindSettingsApi(app core.App, rg *router.RouterGroup[*core.RequestEvent]) {
subGroup.PATCH("", settingsSet)
subGroup.POST("/test/s3", settingsTestS3)
subGroup.POST("/test/email", settingsTestEmail)
+
+ // @todo move to collections
subGroup.POST("/apple/generate-client-secret", settingsGenerateAppleClientSecret)
}
@@ -62,12 +64,12 @@ func settingsSet(e *core.RequestEvent) error {
return e.BadRequestError("An error occurred while saving the new settings.", err)
}
- appSettings, err := e.App.Settings().Clone()
- if err != nil {
- return e.InternalServerError("Failed to clone app settings.", err)
- }
-
return execAfterSuccessTx(true, e.App, func() error {
+ appSettings, err := e.App.Settings().Clone()
+ if err != nil {
+ return e.InternalServerError("Failed to clone app settings.", err)
+ }
+
return e.JSON(http.StatusOK, appSettings)
})
})
diff --git a/core/app.go b/core/app.go
index 57875d0e..729f1175 100644
--- a/core/app.go
+++ b/core/app.go
@@ -267,6 +267,15 @@ type App interface {
// "dangerousSelectQuery" argument must come only from trusted input!
CreateViewFields(dangerousSelectQuery string) (FieldsList, error)
+ // DryRunView executes the provided query by creating a temporary view
+ // collection and returning a sample of the resulting query records (if valid).
+ //
+ // The same caveats from CreateViewFields apply here too.
+ //
+ // NB! Be aware that this method is vulnerable to SQL injection and the
+ // "dangerousSelectQuery" argument must come only from trusted input!
+ DryRunView(dangerousSelectQuery string, sampleSize int) (*DryRunViewResult, error)
+
// FindRecordByViewFile returns the original Record of the provided view collection file.
FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error)
diff --git a/core/collection_model_test.go b/core/collection_model_test.go
index f8fca426..c328118e 100644
--- a/core/collection_model_test.go
+++ b/core/collection_model_test.go
@@ -817,19 +817,19 @@ func TestCollectionDBExport(t *testing.T) {
}{
{
"unknown",
- `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"unknown","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
+ `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"unknown","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
},
{
core.CollectionTypeBase,
- `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"base","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
+ `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"base","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
},
{
core.CollectionTypeView,
- `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"viewQuery":"select 1"},"system":true,"type":"view","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
+ `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"viewQuery":"select 1"},"system":true,"type":"view","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
},
{
core.CollectionTypeAuth,
- `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":null,"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":null},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
+ `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":null,"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":null},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
},
}
@@ -1576,60 +1576,62 @@ func TestCollectionSaveViewWrapping(t *testing.T) {
viewName := "test_wrapping"
+ // note: some of the queries use "limit 0" because the tested field value could be empty
+ // which will trigger the extra sample records validation that are not important for this test
scenarios := []struct {
name string
query string
expected string
}{
{
- "no wrapping - text field",
- "select text as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1)",
+ "no wrapping - id field",
+ "select id, bool from demo1",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select id, bool from demo1)",
},
{
- "no wrapping - id field",
- "select text as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1)",
+ "no wrapping - text field",
+ "select text as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1 limit 0)",
},
{
"no wrapping - relation field",
- "select rel_one as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select rel_one as id, bool from demo1)",
+ "select rel_one as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select rel_one as id, bool from demo1 limit 0)",
},
{
"no wrapping - select field",
- "select select_many as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select select_many as id, bool from demo1)",
+ "select select_many as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select select_many as id, bool from demo1 limit 0)",
},
{
"no wrapping - email field",
- "select email as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select email as id, bool from demo1)",
+ "select email as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select email as id, bool from demo1 limit 0)",
},
{
"no wrapping - datetime field",
- "select datetime as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select datetime as id, bool from demo1)",
+ "select datetime as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select datetime as id, bool from demo1 limit 0)",
},
{
"no wrapping - url field",
- "select url as id, bool from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (select url as id, bool from demo1)",
+ "select url as id, bool from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (select url as id, bool from demo1 limit 0)",
},
{
"wrapping - bool field",
- "select bool as id, text as txt, url from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`txt`,`url` FROM (select bool as id, text as txt, url from demo1))",
+ "select bool as id, text as txt, url from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`txt`,`url` FROM (select bool as id, text as txt, url from demo1 limit 0))",
},
{
"wrapping - bool field (different order)",
- "select text as txt, url, bool as id from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT `txt`,`url`,CAST(`id` as TEXT) `id` FROM (select text as txt, url, bool as id from demo1))",
+ "select text as txt, url, bool as id from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT `txt`,`url`,CAST(`id` as TEXT) `id` FROM (select text as txt, url, bool as id from demo1 limit 0))",
},
{
"wrapping - json field",
- "select json as id, text, url from demo1",
- "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`text`,`url` FROM (select json as id, text, url from demo1))",
+ "select json as id, text, url from demo1 limit 0",
+ "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`text`,`url` FROM (select json as id, text, url from demo1 limit 0))",
},
{
"wrapping - numeric id",
diff --git a/core/collection_model_view_options_test.go b/core/collection_model_view_options_test.go
index c7da1eff..cb50bbb5 100644
--- a/core/collection_model_view_options_test.go
+++ b/core/collection_model_view_options_test.go
@@ -41,6 +41,24 @@ func TestCollectionViewOptionsValidate(t *testing.T) {
},
expectedErrors: []string{"fields", "viewQuery"},
},
+ {
+ name: "view with valid query but empty sample id",
+ collection: func(app core.App) (*core.Collection, error) {
+ c := core.NewViewCollection("new_auth")
+ c.ViewQuery = "select '' as id"
+ return c, nil
+ },
+ expectedErrors: []string{"viewQuery"},
+ },
+ {
+ name: "view with valid query but duplicated sample id",
+ collection: func(app core.App) (*core.Collection, error) {
+ c := core.NewViewCollection("new_auth")
+ c.ViewQuery = "(select 'a' as id union all select 'a' as id union all select 'c' as id)"
+ return c, nil
+ },
+ expectedErrors: []string{"viewQuery"},
+ },
{
name: "view with valid query",
collection: func(app core.App) (*core.Collection, error) {
diff --git a/core/collection_validate.go b/core/collection_validate.go
index ca4c654a..5b83bb8d 100644
--- a/core/collection_validate.go
+++ b/core/collection_validate.go
@@ -314,11 +314,15 @@ func (cv *collectionValidator) checkViewQuery(value any) error {
return nil // nothing to check
}
- if _, err := cv.app.CreateViewFields(v); err != nil {
- return validation.NewError(
- "validation_invalid_view_query",
- fmt.Sprintf("Invalid query - %s", err.Error()),
- )
+ _, err := cv.app.DryRunView(v, 10)
+ if err != nil {
+ rawErr := err.Error()
+ if len(rawErr) > 500 {
+ // restrict just as an extra precaution
+ rawErr = rawErr[:500]
+ }
+
+ return validation.NewError("validation_invalid_view_query", "Invalid query - "+rawErr)
}
return nil
diff --git a/core/events.go b/core/events.go
index 4a03af62..f0da6ea2 100644
--- a/core/events.go
+++ b/core/events.go
@@ -2,6 +2,7 @@ package core
import (
"context"
+ "io/fs"
"net"
"net/http"
"time"
@@ -57,6 +58,9 @@ type baseCollectionEventData struct {
Collection *Collection
}
+// @todo consider storing the original collection name and use that as a tag
+// to avoid the ambiguity when the collection is being modified (#7613);
+// for new collection also maybe return empty tags?
func (e *baseCollectionEventData) Tags() []string {
if e.Collection == nil {
return nil
@@ -125,6 +129,21 @@ type ServeEvent struct {
//
// Set it to nil if you want to skip the installer.
InstallerFunc func(app App, systemSuperuser *Record, baseURL string) error
+
+ // @todo experimental
+ //
+ // UIExtensions is a list with the superuser UI extensions.
+ UIExtensions []UIExtension
+}
+
+type UIExtension struct {
+ // Name is the name of the extension.
+ // It is also used as path segment for the registered public extension endpoint
+ // (e.g. /_/extensions/{name}/*)
+ Name string
+
+ // FS is the extension file system.
+ FS fs.FS
}
// -------------------------------------------------------------------
diff --git a/core/field.go b/core/field.go
index 8ee4d502..0ccf78ba 100644
--- a/core/field.go
+++ b/core/field.go
@@ -184,6 +184,26 @@ type RecordInterceptor interface {
) error
}
+// DefaultFieldHelpValidationRule performs base validation on a field's "help" value.
+func DefaultFieldHelpValidationRule(value any) error {
+ v, ok := value.(string)
+ if !ok {
+ return validators.ErrUnsupportedValueType
+ }
+
+ rules := []validation.Rule{
+ validation.Length(1, 300),
+ }
+
+ for _, r := range rules {
+ if err := r.Validate(v); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
// DefaultFieldIdValidationRule performs base validation on a field id value.
func DefaultFieldIdValidationRule(value any) error {
v, ok := value.(string)
diff --git a/core/field_autodate.go b/core/field_autodate.go
index ca29bed2..8239d090 100644
--- a/core/field_autodate.go
+++ b/core/field_autodate.go
@@ -46,12 +46,12 @@ type AutodateField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
-
// OnCreate auto sets the current datetime as field value on record create.
OnCreate bool `form:"onCreate" json:"onCreate"`
diff --git a/core/field_bool.go b/core/field_bool.go
index 7be98c2a..f737c834 100644
--- a/core/field_bool.go
+++ b/core/field_bool.go
@@ -36,11 +36,15 @@ type BoolField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Required will require the field value to be always "true".
Required bool `form:"required" json:"required"`
@@ -120,5 +124,6 @@ func (f *BoolField) ValidateSettings(ctx context.Context, app App, collection *C
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
)
}
diff --git a/core/field_bool_test.go b/core/field_bool_test.go
index 6706099b..1c45428f 100644
--- a/core/field_bool_test.go
+++ b/core/field_bool_test.go
@@ -147,4 +147,5 @@ func TestBoolFieldValidateValue(t *testing.T) {
func TestBoolFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeBool)
testDefaultFieldNameValidation(t, core.FieldTypeBool)
+ testDefaultFieldHelpValidation[core.BoolField](t)
}
diff --git a/core/field_date.go b/core/field_date.go
index 67ee1ebf..81f2e9d8 100644
--- a/core/field_date.go
+++ b/core/field_date.go
@@ -36,11 +36,15 @@ type DateField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Min specifies the min allowed field value.
//
@@ -148,6 +152,7 @@ func (f *DateField) ValidateSettings(ctx context.Context, app App, collection *C
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.Max, validation.By(f.checkRange(f.Min, f.Max))),
)
}
diff --git a/core/field_date_test.go b/core/field_date_test.go
index ea95b191..27cacf4d 100644
--- a/core/field_date_test.go
+++ b/core/field_date_test.go
@@ -133,6 +133,7 @@ func TestDateFieldValidateValue(t *testing.T) {
func TestDateFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeDate)
testDefaultFieldNameValidation(t, core.FieldTypeDate)
+ testDefaultFieldHelpValidation[core.DateField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_editor.go b/core/field_editor.go
index e3f17489..629d6be8 100644
--- a/core/field_editor.go
+++ b/core/field_editor.go
@@ -41,11 +41,15 @@ type EditorField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1).
//
@@ -148,6 +152,7 @@ func (f *EditorField) ValidateSettings(ctx context.Context, app App, collection
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)),
)
}
diff --git a/core/field_editor_test.go b/core/field_editor_test.go
index 8bcebcd7..2b29ffd5 100644
--- a/core/field_editor_test.go
+++ b/core/field_editor_test.go
@@ -163,6 +163,7 @@ func TestEditorFieldValidateValue(t *testing.T) {
func TestEditorFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeEditor)
testDefaultFieldNameValidation(t, core.FieldTypeEditor)
+ testDefaultFieldHelpValidation[core.EditorField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_email.go b/core/field_email.go
index 9d82ac1d..a68b0298 100644
--- a/core/field_email.go
+++ b/core/field_email.go
@@ -39,11 +39,15 @@ type EmailField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// ExceptDomains will require the email domain to NOT be included in the listed ones.
//
@@ -155,6 +159,7 @@ func (f *EmailField) ValidateSettings(ctx context.Context, app App, collection *
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(
&f.ExceptDomains,
validation.When(len(f.OnlyDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)),
diff --git a/core/field_email_test.go b/core/field_email_test.go
index 600f2c2c..0cff54dd 100644
--- a/core/field_email_test.go
+++ b/core/field_email_test.go
@@ -182,6 +182,7 @@ func TestEmailFieldValidateValue(t *testing.T) {
func TestEmailFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeEmail)
testDefaultFieldNameValidation(t, core.FieldTypeEmail)
+ testDefaultFieldHelpValidation[core.EmailField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_file.go b/core/field_file.go
index ad53a3e8..0e773277 100644
--- a/core/field_file.go
+++ b/core/field_file.go
@@ -88,11 +88,15 @@ type FileField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// MaxSize specifies the maximum size of a single uploaded file (in bytes and up to 2^53-1).
//
@@ -223,6 +227,7 @@ func (f *FileField) ValidateSettings(ctx context.Context, app App, collection *C
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.MaxSelect, validation.Min(0), validation.Max(maxSafeJSONInt)),
validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)),
validation.Field(&f.Thumbs, validation.Each(
diff --git a/core/field_file_test.go b/core/field_file_test.go
index 82ad3694..0e210050 100644
--- a/core/field_file_test.go
+++ b/core/field_file_test.go
@@ -443,6 +443,7 @@ func TestFileFieldValidateValue(t *testing.T) {
func TestFileFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeFile)
testDefaultFieldNameValidation(t, core.FieldTypeFile)
+ testDefaultFieldHelpValidation[core.FileField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_geo_point.go b/core/field_geo_point.go
index eecc4186..542abe85 100644
--- a/core/field_geo_point.go
+++ b/core/field_geo_point.go
@@ -46,11 +46,15 @@ type GeoPointField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Required will require the field coordinates to be non-zero (aka. not "Null Island").
Required bool `form:"required" json:"required"`
@@ -144,5 +148,6 @@ func (f *GeoPointField) ValidateSettings(ctx context.Context, app App, collectio
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
)
}
diff --git a/core/field_geo_point_test.go b/core/field_geo_point_test.go
index dfee422f..2800a4f2 100644
--- a/core/field_geo_point_test.go
+++ b/core/field_geo_point_test.go
@@ -199,4 +199,5 @@ func TestGeoPointFieldValidateValue(t *testing.T) {
func TestGeoPointFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeGeoPoint)
testDefaultFieldNameValidation(t, core.FieldTypeGeoPoint)
+ testDefaultFieldHelpValidation[core.GeoPointField](t)
}
diff --git a/core/field_json.go b/core/field_json.go
index 4a30edfc..aa4954d7 100644
--- a/core/field_json.go
+++ b/core/field_json.go
@@ -45,11 +45,15 @@ type JSONField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1).
//
@@ -181,6 +185,7 @@ func (f *JSONField) ValidateSettings(ctx context.Context, app App, collection *C
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)),
)
}
diff --git a/core/field_json_test.go b/core/field_json_test.go
index 75263a99..13eb1f21 100644
--- a/core/field_json_test.go
+++ b/core/field_json_test.go
@@ -188,6 +188,7 @@ func TestJSONFieldValidateValue(t *testing.T) {
func TestJSONFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeJSON)
testDefaultFieldNameValidation(t, core.FieldTypeJSON)
+ testDefaultFieldHelpValidation[core.JSONField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_number.go b/core/field_number.go
index d11e1750..7f4855cb 100644
--- a/core/field_number.go
+++ b/core/field_number.go
@@ -48,11 +48,15 @@ type NumberField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Min specifies the min allowed field value.
//
@@ -173,6 +177,7 @@ func (f *NumberField) ValidateSettings(ctx context.Context, app App, collection
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.Min, validation.By(f.checkOnlyInt)),
validation.Field(&f.Max, maxRules...),
)
diff --git a/core/field_number_test.go b/core/field_number_test.go
index a9117d6b..eae6fb4d 100644
--- a/core/field_number_test.go
+++ b/core/field_number_test.go
@@ -214,6 +214,7 @@ func TestNumberFieldValidateValue(t *testing.T) {
func TestNumberFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeNumber)
testDefaultFieldNameValidation(t, core.FieldTypeNumber)
+ testDefaultFieldHelpValidation[core.NumberField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_password.go b/core/field_password.go
index 794846f7..ed1b1d5d 100644
--- a/core/field_password.go
+++ b/core/field_password.go
@@ -61,11 +61,17 @@ type PasswordField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
+ // @todo remove
+ //
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Pattern specifies an optional regex pattern to match against the field value.
//
@@ -209,6 +215,7 @@ func (f *PasswordField) ValidateSettings(ctx context.Context, app App, collectio
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.Min, validation.Min(1), validation.Max(71)),
validation.Field(&f.Max, validation.Min(f.Min), validation.Max(71)),
validation.Field(&f.Cost, validation.Min(bcrypt.MinCost), validation.Max(bcrypt.MaxCost)),
diff --git a/core/field_password_test.go b/core/field_password_test.go
index 31a1113d..39733e62 100644
--- a/core/field_password_test.go
+++ b/core/field_password_test.go
@@ -287,6 +287,7 @@ func TestPasswordFieldValidateValue(t *testing.T) {
func TestPasswordFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypePassword)
testDefaultFieldNameValidation(t, core.FieldTypePassword)
+ testDefaultFieldHelpValidation[core.PasswordField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_relation.go b/core/field_relation.go
index 77956457..bf75674a 100644
--- a/core/field_relation.go
+++ b/core/field_relation.go
@@ -66,11 +66,15 @@ type RelationField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// CollectionId is the id of the related collection.
CollectionId string `form:"collectionId" json:"collectionId"`
@@ -237,6 +241,7 @@ func (f *RelationField) ValidateSettings(ctx context.Context, app App, collectio
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.CollectionId, validation.Required, validation.By(f.checkCollectionId(app, collection))),
validation.Field(&f.MinSelect, validation.Min(0)),
validation.Field(&f.MaxSelect, validation.When(f.MinSelect > 0, validation.Required), validation.Min(f.MinSelect)),
diff --git a/core/field_relation_test.go b/core/field_relation_test.go
index 598e361b..501530fe 100644
--- a/core/field_relation_test.go
+++ b/core/field_relation_test.go
@@ -348,6 +348,7 @@ func TestRelationFieldValidateValue(t *testing.T) {
func TestRelationFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeRelation)
testDefaultFieldNameValidation(t, core.FieldTypeRelation)
+ testDefaultFieldHelpValidation[core.RelationField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_select.go b/core/field_select.go
index e77eb38c..8b1c5c9d 100644
--- a/core/field_select.go
+++ b/core/field_select.go
@@ -66,11 +66,15 @@ type SelectField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Values specifies the list of accepted values.
Values []string `form:"values" json:"values"`
@@ -216,6 +220,7 @@ func (f *SelectField) ValidateSettings(ctx context.Context, app App, collection
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.Values, validation.Required),
validation.Field(&f.MaxSelect, validation.Min(0), validation.Max(max)),
)
diff --git a/core/field_select_test.go b/core/field_select_test.go
index 808c1096..093c7011 100644
--- a/core/field_select_test.go
+++ b/core/field_select_test.go
@@ -337,6 +337,7 @@ func TestSelectFieldValidateValue(t *testing.T) {
func TestSelectFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeSelect)
testDefaultFieldNameValidation(t, core.FieldTypeSelect)
+ testDefaultFieldHelpValidation[core.SelectField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_test.go b/core/field_test.go
index fba7089a..158dde2e 100644
--- a/core/field_test.go
+++ b/core/field_test.go
@@ -2,6 +2,8 @@ package core_test
import (
"context"
+ "encoding/json"
+ "reflect"
"strings"
"testing"
@@ -113,7 +115,7 @@ func testDefaultFieldIdValidation(t *testing.T, fieldType string) {
hasErr := errs["id"] != nil
if hasErr != s.expectError {
- t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr)
+ t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs)
}
})
}
@@ -254,7 +256,64 @@ func testDefaultFieldNameValidation(t *testing.T, fieldType string) {
hasErr := errs["name"] != nil
if hasErr != s.expectError {
- t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr)
+ t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs)
+ }
+ })
+ }
+}
+
+func testDefaultFieldHelpValidation[T any](t *testing.T) {
+ app, _ := tests.NewTestApp()
+ defer app.Cleanup()
+
+ collection := core.NewBaseCollection("test_collection")
+
+ scenarios := []struct {
+ name string
+ json string
+ expectError bool
+ }{
+ {
+ "empty value",
+ `{}`,
+ false,
+ },
+ {
+ "< max limit",
+ `{"help":"abc"}`,
+ false,
+ },
+ {
+ "= max limit",
+ `{"help":"` + strings.Repeat("a", 300) + `"}`,
+ false,
+ },
+ {
+ "> max limit",
+ `{"help":"` + strings.Repeat("a", 301) + `"}`,
+ true,
+ },
+ }
+
+ for _, s := range scenarios {
+ t.Run("[help] "+s.name, func(t *testing.T) {
+ var zeroField T
+
+ field, ok := reflect.New(reflect.TypeOf(zeroField)).Interface().(core.Field)
+ if !ok {
+ t.Fatalf("Expected core.Field instance, got %T", zeroField)
+ }
+
+ err := json.Unmarshal([]byte(s.json), &field)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ errs, _ := field.ValidateSettings(context.Background(), app, collection).(validation.Errors)
+
+ hasErr := errs["help"] != nil
+ if hasErr != s.expectError {
+ t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs)
}
})
}
diff --git a/core/field_text.go b/core/field_text.go
index 75439fad..2a2af532 100644
--- a/core/field_text.go
+++ b/core/field_text.go
@@ -72,11 +72,15 @@ type TextField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// Min specifies the minimum required string characters.
//
@@ -283,6 +287,7 @@ func (f *TextField) ValidateSettings(ctx context.Context, app App, collection *C
validation.By(DefaultFieldNameValidationRule),
validation.When(f.PrimaryKey, validation.In(idColumn).Error(`The primary key must be named "id".`)),
),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(&f.PrimaryKey, validation.By(f.checkOtherFieldsForPK(collection))),
validation.Field(&f.Min, validation.Min(0), validation.Max(maxSafeJSONInt)),
validation.Field(&f.Max, validation.Min(f.Min), validation.Max(maxSafeJSONInt)),
diff --git a/core/field_text_test.go b/core/field_text_test.go
index 94357d18..671a6575 100644
--- a/core/field_text_test.go
+++ b/core/field_text_test.go
@@ -381,6 +381,7 @@ func TestTextFieldValidateValue(t *testing.T) {
func TestTextFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeText)
testDefaultFieldNameValidation(t, core.FieldTypeText)
+ testDefaultFieldHelpValidation[core.TextField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/field_url.go b/core/field_url.go
index 79a61dc3..06d6d856 100644
--- a/core/field_url.go
+++ b/core/field_url.go
@@ -39,11 +39,15 @@ type URLField struct {
// Hidden hides the field from the API response.
Hidden bool `form:"hidden" json:"hidden"`
+ // ---
+
// Presentable hints the Dashboard UI to use the underlying
// field record value in the relation preview label.
Presentable bool `form:"presentable" json:"presentable"`
- // ---
+ // Help is an extra text explaining what the field is about.
+ // It is usually shown in Dashboard UI under the field input.
+ Help string `form:"help" json:"help"`
// ExceptDomains will require the URL domain to NOT be included in the listed ones.
//
@@ -156,6 +160,7 @@ func (f *URLField) ValidateSettings(ctx context.Context, app App, collection *Co
return validation.ValidateStruct(f,
validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)),
validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)),
+ validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)),
validation.Field(
&f.ExceptDomains,
validation.When(len(f.OnlyDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)),
diff --git a/core/field_url_test.go b/core/field_url_test.go
index 0b2db39d..7f59e069 100644
--- a/core/field_url_test.go
+++ b/core/field_url_test.go
@@ -182,6 +182,7 @@ func TestURLFieldValidateValue(t *testing.T) {
func TestURLFieldValidateSettings(t *testing.T) {
testDefaultFieldIdValidation(t, core.FieldTypeURL)
testDefaultFieldNameValidation(t, core.FieldTypeURL)
+ testDefaultFieldHelpValidation[core.URLField](t)
app, _ := tests.NewTestApp()
defer app.Cleanup()
diff --git a/core/fields_list_test.go b/core/fields_list_test.go
index e667e769..13457e39 100644
--- a/core/fields_list_test.go
+++ b/core/fields_list_test.go
@@ -473,13 +473,13 @@ func TestFieldsListScan(t *testing.T) {
"only the minimum field options",
`[{"id":"123","name":"test1","type":"text","required":true},{"id":"456","name":"test2","type":"bool"}]`,
false,
- `[{"autogeneratePattern":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`,
},
{
"all field options",
- `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
false,
- `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
},
}
@@ -523,13 +523,13 @@ func TestFieldsListJSON(t *testing.T) {
"only the minimum field options",
`[{"id":"123","name":"test1","type":"text","required":true},{"id":"456","name":"test2","type":"bool"}]`,
false,
- `[{"autogeneratePattern":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`,
},
{
"all field options",
- `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
false,
- `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
+ `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`,
},
}
diff --git a/core/settings_model.go b/core/settings_model.go
index a1100001..1adead7b 100644
--- a/core/settings_model.go
+++ b/core/settings_model.go
@@ -143,6 +143,7 @@ func newDefaultSettings() *Settings {
isNew: true,
settings: settings{
Meta: MetaConfig{
+ AccentColor: "#1055c9",
AppName: "Acme",
AppURL: "http://localhost:8090",
HideControls: false,
@@ -513,6 +514,11 @@ func checkCronExpression(value any) error {
// -------------------------------------------------------------------
type MetaConfig struct {
+ // @todo experimental
+ //
+ // AccentColor specify the UI "accent" color (HEX).
+ AccentColor string `form:"accentColor" json:"accentColor"`
+
AppName string `form:"appName" json:"appName"`
AppURL string `form:"appURL" json:"appURL"`
SenderName string `form:"senderName" json:"senderName"`
@@ -523,6 +529,7 @@ type MetaConfig struct {
// Validate makes MetaConfig validatable by implementing [validation.Validatable] interface.
func (c MetaConfig) Validate() error {
return validation.ValidateStruct(&c,
+ validation.Field(&c.AccentColor, validation.Length(7, 7), is.HexColor),
validation.Field(&c.AppName, validation.Required, validation.Length(1, 255)),
validation.Field(&c.AppURL, validation.Required, is.URL),
validation.Field(&c.SenderName, validation.Required, validation.Length(1, 255)),
diff --git a/core/settings_model_test.go b/core/settings_model_test.go
index b0ea8983..5f577f8d 100644
--- a/core/settings_model_test.go
+++ b/core/settings_model_test.go
@@ -84,7 +84,7 @@ func TestSettings_DBExport(t *testing.T) {
valueStr = string(export["value"].([]byte))
}
- expected := `{"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}`
+ expected := `{"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"accentColor":"","appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}`
if valueStr != expected {
t.Fatalf("Expected exported settings\n%s\ngot\n%s", expected, valueStr)
}
@@ -93,6 +93,8 @@ func TestSettings_DBExport(t *testing.T) {
}
func TestSettingsMerge(t *testing.T) {
+ t.Parallel()
+
s1 := &core.Settings{}
s1.Meta.AppURL = "app_url" // should be unset
@@ -126,6 +128,8 @@ func TestSettingsMerge(t *testing.T) {
}
func TestSettingsClone(t *testing.T) {
+ t.Parallel()
+
s1 := &core.Settings{}
s1.Meta.AppName = "test_name"
@@ -156,6 +160,8 @@ func TestSettingsClone(t *testing.T) {
}
func TestSettingsMarshalJSON(t *testing.T) {
+ t.Parallel()
+
settings := &core.Settings{}
// control fields
@@ -174,7 +180,7 @@ func TestSettingsMarshalJSON(t *testing.T) {
}
rawStr := string(raw)
- expected := `{"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}`
+ expected := `{"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"accentColor":"","appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}`
if rawStr != expected {
t.Fatalf("Expected\n%v\ngot\n%v", expected, rawStr)
@@ -230,6 +236,8 @@ func TestSettingsValidate(t *testing.T) {
}
func TestMetaConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.MetaConfig
@@ -248,12 +256,14 @@ func TestMetaConfigValidate(t *testing.T) {
{
"invalid data",
core.MetaConfig{
+ AccentColor: "#fff",
AppName: strings.Repeat("a", 300),
AppURL: "test",
SenderName: strings.Repeat("a", 300),
SenderAddress: "invalid_email",
},
[]string{
+ "accentColor",
"appName",
"appURL",
"senderName",
@@ -263,6 +273,7 @@ func TestMetaConfigValidate(t *testing.T) {
{
"valid data",
core.MetaConfig{
+ AccentColor: "#ffffff",
AppName: "test",
AppURL: "https://example.com",
SenderName: "test",
@@ -282,6 +293,8 @@ func TestMetaConfigValidate(t *testing.T) {
}
func TestLogsConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.LogsConfig
@@ -314,6 +327,8 @@ func TestLogsConfigValidate(t *testing.T) {
}
func TestSMTPConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.SMTPConfig
@@ -373,6 +388,8 @@ func TestSMTPConfigValidate(t *testing.T) {
}
func TestS3ConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.S3Config
@@ -444,6 +461,8 @@ func TestS3ConfigValidate(t *testing.T) {
}
func TestBackupsConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.BackupsConfig
@@ -499,6 +518,8 @@ func TestBackupsConfigValidate(t *testing.T) {
}
func TestBatchConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.BatchConfig
@@ -554,6 +575,8 @@ func TestBatchConfigValidate(t *testing.T) {
}
func TestRateLimitsConfigValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
config core.RateLimitsConfig
@@ -699,6 +722,8 @@ func TestRateLimitsConfigValidate(t *testing.T) {
}
func TestRateLimitsFindRateLimitRule(t *testing.T) {
+ t.Parallel()
+
limits := core.RateLimitsConfig{
Rules: []core.RateLimitRule{
{Label: "abc"},
@@ -753,6 +778,8 @@ func TestRateLimitsFindRateLimitRule(t *testing.T) {
}
func TestRateLimitRuleValidate(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
rule core.RateLimitRule
@@ -860,6 +887,8 @@ func TestRateLimitRuleValidate(t *testing.T) {
}
func TestRateLimitRuleDurationTime(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
rule core.RateLimitRule
expected time.Duration
@@ -880,6 +909,8 @@ func TestRateLimitRuleDurationTime(t *testing.T) {
}
func TestRateLimitRuleString(t *testing.T) {
+ t.Parallel()
+
scenarios := []struct {
name string
rule core.RateLimitRule
diff --git a/core/view.go b/core/view.go
index fdfefdf2..5b44e8bc 100644
--- a/core/view.go
+++ b/core/view.go
@@ -1,6 +1,7 @@
package core
import (
+ "context"
"errors"
"fmt"
"io"
@@ -36,17 +37,14 @@ func (app *BaseApp) DeleteView(dangerousViewName string) error {
func (app *BaseApp) SaveView(dangerousViewName string, dangerousSelectQuery string) error {
return app.RunInTransaction(func(txApp App) error {
// delete old view (if exists)
- if err := txApp.DeleteView(dangerousViewName); err != nil {
+ err := txApp.DeleteView(dangerousViewName)
+ if err != nil {
return err
}
- dangerousSelectQuery = strings.Trim(strings.TrimSpace(dangerousSelectQuery), ";")
-
- // try to loosely detect multiple inline statements
- tk := tokenizer.NewFromString(dangerousSelectQuery)
- tk.Separators(';')
- if queryParts, _ := tk.ScanAll(); len(queryParts) > 1 {
- return errors.New("multiple statements are not supported")
+ dangerousSelectQuery, err = normalizeViewSelectQuery(dangerousSelectQuery)
+ if err != nil {
+ return err
}
// (re)create the view
@@ -54,7 +52,8 @@ func (app *BaseApp) SaveView(dangerousViewName string, dangerousSelectQuery stri
// note: the query is wrapped in a secondary SELECT as a rudimentary
// measure to discourage multiple inline sql statements execution
viewQuery := fmt.Sprintf("CREATE VIEW {{%s}} AS SELECT * FROM (%s)", dangerousViewName, dangerousSelectQuery)
- if _, err := txApp.DB().NewQuery(viewQuery).Execute(); err != nil {
+ _, err = txApp.DB().NewQuery(viewQuery).Execute()
+ if err != nil {
return err
}
@@ -124,6 +123,76 @@ func (app *BaseApp) CreateViewFields(dangerousSelectQuery string) (FieldsList, e
return result, txErr
}
+type DryRunViewResult struct {
+ Fields FieldsList `json:"fields"`
+ Sample []*Record `json:"sample"`
+}
+
+// DryRunView executes the provided query by creating a temporary view
+// collection and returning a sample of the resulting query records (if valid).
+//
+// The same caveats from CreateViewFields apply here too.
+//
+// NB! Be aware that this method is vulnerable to SQL injection and the
+// "dangerousSelectQuery" argument must come only from trusted input!
+func (app *BaseApp) DryRunView(dangerousSelectQuery string, sampleSize int) (*DryRunViewResult, error) {
+ dangerousSelectQuery, err := normalizeViewSelectQuery(dangerousSelectQuery)
+ if err != nil {
+ return nil, err
+ }
+
+ fields, err := app.CreateViewFields(dangerousSelectQuery)
+ if err != nil {
+ return nil, err
+ }
+
+ tempName := "temp_view_" + security.RandomString(5)
+ tempCollection := NewViewCollection(tempName)
+ tempCollection.Fields = fields
+
+ // validate generated view fields
+ ctx := context.Background()
+ for i, f := range fields {
+ err = f.ValidateSettings(ctx, app, tempCollection)
+ if err != nil {
+ return nil, fmt.Errorf("invalid field %q (%d): %w", f.GetName(), i, err)
+ }
+ }
+
+ records := []*Record{}
+
+ err = app.RecordQuery(tempCollection).
+ // note: the query is wrapped in a secondary SELECT as a rudimentary
+ // measure to discourage multiple inline sql statements execution
+ From("(SELECT * FROM (" + dangerousSelectQuery + ")) as " + tempName).
+ Limit(int64(sampleSize)).
+ All(&records)
+ if err != nil {
+ return nil, fmt.Errorf("failed to retrieve query records: %w", err)
+ }
+
+ // warn for possible empty or duplicated record ids found in the sample
+ // (it is not intended for security and it is here to quickly provide a
+ // helpful error message without doing multiple query executions)
+ ids := make(map[string]struct{}, len(records))
+ for _, r := range records {
+ if r.Id == "" {
+ return nil, errors.New("the query could return records with empty or invalid ids")
+ }
+
+ if _, ok := ids[r.Id]; ok {
+ return nil, errors.New("the query could return records with non-unique ids")
+ }
+
+ ids[r.Id] = struct{}{}
+ }
+
+ return &DryRunViewResult{
+ Fields: fields,
+ Sample: records,
+ }, nil
+}
+
// FindRecordByViewFile returns the original Record of the provided view collection file.
func (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) {
view, err := getCollectionByModelOrIdentifier(app, viewCollectionModelOrIdentifier)
@@ -198,6 +267,20 @@ func (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fi
// Raw query to schema helpers
// -------------------------------------------------------------------
+// loosely normalizes the specified view query and warn against multiple inline statements
+// (the check is not perfect and it is NOT intended as a security measure; it is done primarily to provide a helpful error message)
+func normalizeViewSelectQuery(dangerousSelectQuery string) (string, error) {
+ dangerousSelectQuery = strings.Trim(strings.TrimSpace(dangerousSelectQuery), ";")
+
+ tk := tokenizer.NewFromString(dangerousSelectQuery)
+ tk.Separators(';')
+ if queryParts, _ := tk.ScanAll(); len(queryParts) > 1 {
+ return "", errors.New("multiple statements are not supported")
+ }
+
+ return dangerousSelectQuery, nil
+}
+
type queryField struct {
// field is the final resolved field.
field Field
@@ -212,12 +295,26 @@ type queryField struct {
}
func defaultViewField(name string) Field {
+ if name == FieldNameId {
+ return defaultViewIdField()
+ }
+
return &JSONField{
Name: name,
MaxSize: 1, // unused for views
}
}
+func defaultViewIdField() Field {
+ return &TextField{
+ Name: FieldNameId,
+ System: true,
+ Required: true,
+ PrimaryKey: true,
+ Pattern: `^[a-z0-9]+$`,
+ }
+}
+
var castRegex = regexp.MustCompile(`(?is)^cast\s*\(.*\s+as\s+(\w+)\s*\)$`)
func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, error) {
@@ -245,13 +342,7 @@ func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, er
// pk (always assume text field for now)
if col.alias == FieldNameId {
result[col.alias] = &queryField{
- field: &TextField{
- Name: col.alias,
- System: true,
- Required: true,
- PrimaryKey: true,
- Pattern: `^[a-z0-9]+$`,
- },
+ field: defaultViewIdField(),
}
continue
}
diff --git a/core/view_test.go b/core/view_test.go
index 2f717598..384f3e23 100644
--- a/core/view_test.go
+++ b/core/view_test.go
@@ -732,3 +732,129 @@ func TestFindRecordByViewFile(t *testing.T) {
})
}
}
+
+func TestDryRunView(t *testing.T) {
+ t.Parallel()
+
+ app, _ := tests.NewTestApp()
+ defer app.Cleanup()
+
+ scenarios := []struct {
+ name string
+ query string
+ sampleSize int
+ expectError bool
+ expectFields map[string]string // name-type pairs
+ expectSampleIds []string // record ids of the resulting sample
+ }{
+ {
+ "empty query",
+ "",
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "non-select query",
+ "CREATE TABLE t1(x INT)",
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "multiple inline select statements",
+ "select 'a' as id; select 'b' as id",
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "select with invalid formatted field name",
+ "select 'a' as id, count(*)", // missing field alias
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "select resolving to records with missing id",
+ "(select 'a' as id UNION ALL select null as id UNION ALL select 'c' as id)",
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "select resolving to records with duplicated ids",
+ "(select 'a' as id UNION ALL select 'a' as id UNION ALL select 'c' as id)",
+ 10,
+ true,
+ nil,
+ nil,
+ },
+ {
+ "no sample size and valid select query but with invalid records result",
+ "(select 'a' as id UNION ALL select 'a' as id UNION ALL select 'c' as id)",
+ 0,
+ false, // still "valid" because there is no sample to check
+ map[string]string{"id": "text"},
+ nil,
+ },
+ {
+ "sample size < total select records",
+ "(select 'a' as id UNION ALL select 'b' as id UNION ALL select 'c' as id UNION ALL select 'd' as id)",
+ 3,
+ false,
+ map[string]string{"id": "text"},
+ []string{"a", "b", "c"},
+ },
+ }
+
+ for _, s := range scenarios {
+ t.Run(s.name, func(t *testing.T) {
+ result, err := app.DryRunView(s.query, s.sampleSize)
+
+ hasErr := err != nil
+ if hasErr != s.expectError {
+ t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, err)
+ }
+
+ if hasErr {
+ return
+ }
+
+ // check fields
+ // ---
+ if len(s.expectFields) != len(result.Fields) {
+ serialized, _ := json.Marshal(result.Fields)
+ t.Fatalf("Expected %d fields, got %d: \n%s", len(s.expectFields), len(result.Fields), serialized)
+ }
+ for name, typ := range s.expectFields {
+ field := result.Fields.GetByName(name)
+ if field == nil {
+ t.Fatalf("Expected to find field %s, got nil", name)
+ }
+
+ if field.Type() != typ {
+ t.Fatalf("Expected field %s to be %q, got %q", name, typ, field.Type())
+ }
+ }
+
+ // check sample ids
+ // ---
+ if len(s.expectSampleIds) != len(result.Sample) {
+ t.Fatalf("Expected %d sample records, got %d", len(s.expectSampleIds), len(result.Sample))
+ }
+ for i, r := range result.Sample {
+ if s.expectSampleIds[i] != r.Id {
+ t.Fatalf("Expected sample record id %q, got %q at %d", s.expectSampleIds[i], r.Id, i)
+ }
+ }
+ })
+ }
+
+ ensureNoTempViews(app, t)
+}
diff --git a/plugins/jsvm/binds.go b/plugins/jsvm/binds.go
index 6ec4b9ff..c76fc749 100644
--- a/plugins/jsvm/binds.go
+++ b/plugins/jsvm/binds.go
@@ -289,9 +289,13 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]*hook.
return wrappedMiddlewares, nil
}
+// -------------------------------------------------------------------
+
var cachedArrayOfTypes = store.New[reflect.Type, reflect.Type](nil)
-func baseBinds(vm *goja.Runtime) {
+// BindCore registers common core objects and functions such as sleep,
+// toString, DynamicModel, etc. into the provided runtime.
+func BindCore(vm *goja.Runtime) {
vm.SetFieldNameMapper(FieldMapper{})
// deprecated: use toString
@@ -659,7 +663,10 @@ func baseBinds(vm *goja.Runtime) {
})
}
-func dbxBinds(vm *goja.Runtime) {
+// BindDbx registers $dbx.* namespaced object with dbx database builder related methods.
+//
+// See https://pocketbase.io/jsvm/modules/_dbx.html.
+func BindDbx(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$dbx", obj)
@@ -682,7 +689,10 @@ func dbxBinds(vm *goja.Runtime) {
obj.Set("notBetween", dbx.NotBetween)
}
-func mailsBinds(vm *goja.Runtime) {
+// BindMails registers $mail.* namespaced object with common mail related helpers.
+//
+// See https://pocketbase.io/jsvm/modules/_mails.html.
+func BindMails(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$mails", obj)
@@ -693,7 +703,10 @@ func mailsBinds(vm *goja.Runtime) {
obj.Set("sendRecordAuthAlert", mails.SendRecordAuthAlert)
}
-func securityBinds(vm *goja.Runtime) {
+// BindSecurity registers $security.* namespaced object with common security related helpers.
+//
+// See https://pocketbase.io/jsvm/modules/_security.html.
+func BindSecurity(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$security", obj)
@@ -736,7 +749,11 @@ func securityBinds(vm *goja.Runtime) {
})
}
-func filesystemBinds(vm *goja.Runtime) {
+// BindFilesystem registers $filesystem.* namespaced object with
+// common filesystem package related helpers.
+//
+// See https://pocketbase.io/jsvm/modules/_filesystem.html.
+func BindFilesystem(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$filesystem", obj)
@@ -757,7 +774,11 @@ func filesystemBinds(vm *goja.Runtime) {
})
}
-func filepathBinds(vm *goja.Runtime) {
+// BindFilesystem registers $filepath.* namespaced object with
+// common std Go filepath package related exports.
+//
+// See https://pocketbase.io/jsvm/modules/_filepath.html.
+func BindFilepath(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$filepath", obj)
@@ -778,7 +799,11 @@ func filepathBinds(vm *goja.Runtime) {
obj.Set("walkDir", filepath.WalkDir)
}
-func osBinds(vm *goja.Runtime) {
+// BindFilesystem registers $os.* namespaced object with
+// common std Go os package related exports.
+//
+// See https://pocketbase.io/jsvm/modules/_os.html.
+func BindOs(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$os", obj)
@@ -804,14 +829,20 @@ func osBinds(vm *goja.Runtime) {
obj.Set("openInRoot", os.OpenInRoot)
}
-func formsBinds(vm *goja.Runtime) {
+// BindForms registers various application form constructors.
+// These bindings are mostly used internally and/or preserved for backward compatibility with earlier versions.
+func BindForms(vm *goja.Runtime) {
registerFactoryAsConstructor(vm, "AppleClientSecretCreateForm", forms.NewAppleClientSecretCreate)
registerFactoryAsConstructor(vm, "RecordUpsertForm", forms.NewRecordUpsert)
registerFactoryAsConstructor(vm, "TestEmailSendForm", forms.NewTestEmailSend)
registerFactoryAsConstructor(vm, "TestS3FilesystemForm", forms.NewTestS3Filesystem)
}
-func apisBinds(vm *goja.Runtime) {
+// BindApis registers $apis.* namespaced object with reusable Web API
+// handlers, middlewares and other related helpers.
+//
+// See https://pocketbase.io/jsvm/modules/_apis.html.
+func BindApis(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$apis", obj)
@@ -850,7 +881,11 @@ func apisBinds(vm *goja.Runtime) {
registerFactoryAsConstructor(vm, "InternalServerError", router.NewInternalServerError)
}
-func httpClientBinds(vm *goja.Runtime) {
+// BindHttpClient registers $http.* namespaced object with common utils
+// for sending HTTP requests.
+//
+// See https://pocketbase.io/jsvm/modules/_http.html.
+func BindHttpClient(vm *goja.Runtime) {
obj := vm.NewObject()
vm.Set("$http", obj)
diff --git a/plugins/jsvm/binds_test.go b/plugins/jsvm/binds_test.go
index 7e4c5121..4accf892 100644
--- a/plugins/jsvm/binds_test.go
+++ b/plugins/jsvm/binds_test.go
@@ -43,16 +43,16 @@ func testBindsCount(vm *goja.Runtime, namespace string, count int, t *testing.T)
// note: this test is useful as a reminder to update the tests in case
// a new base binding is added.
-func TestBaseBindsCount(t *testing.T) {
+func TestBindCoreCount(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
testBindsCount(vm, "this", 41, t)
}
-func TestBaseBindsSleep(t *testing.T) {
+func TestBindCoreSleep(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("reader", strings.NewReader("test"))
start := time.Now()
@@ -69,9 +69,9 @@ func TestBaseBindsSleep(t *testing.T) {
}
}
-func TestBaseBindsReaderToString(t *testing.T) {
+func TestBindCoreReaderToString(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("reader", strings.NewReader("test"))
_, err := vm.RunString(`
@@ -86,9 +86,9 @@ func TestBaseBindsReaderToString(t *testing.T) {
}
}
-func TestBaseBindsToString(t *testing.T) {
+func TestBindCoreToString(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("scenarios", []struct {
Name string
Value any
@@ -120,9 +120,9 @@ func TestBaseBindsToString(t *testing.T) {
}
}
-func TestBaseBindsToBytes(t *testing.T) {
+func TestBindCoreToBytes(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("bytesEqual", bytes.Equal)
vm.Set("scenarios", []struct {
Name string
@@ -160,9 +160,9 @@ func TestBaseBindsToBytes(t *testing.T) {
}
}
-func TestBaseBindsUnmarshal(t *testing.T) {
+func TestBindCoreUnmarshal(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("data", &map[string]any{"a": 123})
_, err := vm.RunString(`
@@ -181,9 +181,9 @@ func TestBaseBindsUnmarshal(t *testing.T) {
}
}
-func TestBaseBindsContext(t *testing.T) {
+func TestBindCoreContext(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const base = new Context(null, "a", 123);
@@ -205,9 +205,9 @@ func TestBaseBindsContext(t *testing.T) {
}
}
-func TestBaseBindsCookie(t *testing.T) {
+func TestBindCoreCookie(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const cookie = new Cookie({
@@ -234,9 +234,9 @@ func TestBaseBindsCookie(t *testing.T) {
}
}
-func TestBaseBindsSubscriptionMessage(t *testing.T) {
+func TestBindCoreSubscriptionMessage(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("bytesToString", func(b []byte) string {
return string(b)
})
@@ -262,7 +262,7 @@ func TestBaseBindsSubscriptionMessage(t *testing.T) {
}
}
-func TestBaseBindsRecord(t *testing.T) {
+func TestBindCoreRecord(t *testing.T) {
app, _ := tests.NewTestApp()
defer app.Cleanup()
@@ -272,7 +272,7 @@ func TestBaseBindsRecord(t *testing.T) {
}
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("collection", collection)
// without record data
@@ -308,9 +308,9 @@ func TestBaseBindsRecord(t *testing.T) {
}
}
-func TestBaseBindsCollection(t *testing.T) {
+func TestBindCoreCollection(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
v, err := vm.RunString(`new Collection({ name: "test", createRule: "@request.auth.id != ''", fields: [{name: "title", "type": "text"}] })`)
if err != nil {
@@ -336,9 +336,9 @@ func TestBaseBindsCollection(t *testing.T) {
}
}
-func TestBaseBindsFieldsList(t *testing.T) {
+func TestBindCoreFieldsList(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
v, err := vm.RunString(`new FieldsList([{name: "title", "type": "text"}])`)
if err != nil {
@@ -355,9 +355,9 @@ func TestBaseBindsFieldsList(t *testing.T) {
}
}
-func TestBaseBindsField(t *testing.T) {
+func TestBindCoreField(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
v, err := vm.RunString(`new Field({name: "test", "type": "bool"})`)
if err != nil {
@@ -379,11 +379,11 @@ func isType[T any](v any) bool {
return ok
}
-func TestBaseBindsNamedFields(t *testing.T) {
+func TestBindCoreNamedFields(t *testing.T) {
t.Parallel()
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
scenarios := []struct {
js string
@@ -470,9 +470,9 @@ func TestBaseBindsNamedFields(t *testing.T) {
}
}
-func TestBaseBindsMailerMessage(t *testing.T) {
+func TestBindCoreMailerMessage(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
v, err := vm.RunString(`new MailerMessage({
from: {name: "test_from", address: "test_from@example.com"},
@@ -517,9 +517,9 @@ func TestBaseBindsMailerMessage(t *testing.T) {
}
}
-func TestBaseBindsCommand(t *testing.T) {
+func TestBindCoreCommand(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
let runCalls = 0;
@@ -546,9 +546,9 @@ func TestBaseBindsCommand(t *testing.T) {
}
}
-func TestBaseBindsRequestInfo(t *testing.T) {
+func TestBindCoreRequestInfo(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const info = new RequestInfo({
@@ -564,9 +564,9 @@ func TestBaseBindsRequestInfo(t *testing.T) {
}
}
-func TestBaseBindsMiddleware(t *testing.T) {
+func TestBindCoreMiddleware(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const m = new Middleware(
@@ -584,9 +584,9 @@ func TestBaseBindsMiddleware(t *testing.T) {
}
}
-func TestBaseBindsTimezone(t *testing.T) {
+func TestBindCoreTimezone(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const v0 = (new Timezone()).string();
@@ -609,9 +609,9 @@ func TestBaseBindsTimezone(t *testing.T) {
}
}
-func TestBaseBindsDateTime(t *testing.T) {
+func TestBindCoreDateTime(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
_, err := vm.RunString(`
const now = new DateTime();
@@ -650,9 +650,9 @@ func TestBaseBindsDateTime(t *testing.T) {
}
}
-func TestBaseBindsValidationError(t *testing.T) {
+func TestBindCoreValidationError(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
scenarios := []struct {
js string
@@ -697,14 +697,14 @@ func TestBaseBindsValidationError(t *testing.T) {
}
}
-func TestDbxBinds(t *testing.T) {
+func TestBindDbx(t *testing.T) {
app, _ := tests.NewTestApp()
defer app.Cleanup()
vm := goja.New()
vm.Set("db", app.DB())
- baseBinds(vm)
- dbxBinds(vm)
+ BindCore(vm)
+ BindDbx(vm)
testBindsCount(vm, "$dbx", 15, t)
@@ -792,14 +792,14 @@ func TestDbxBinds(t *testing.T) {
}
}
-func TestMailsBindsCount(t *testing.T) {
+func TestBindMailsCount(t *testing.T) {
vm := goja.New()
- mailsBinds(vm)
+ BindMails(vm)
testBindsCount(vm, "$mails", 5, t)
}
-func TestMailsBinds(t *testing.T) {
+func TestBindMails(t *testing.T) {
app, _ := tests.NewTestApp()
defer app.Cleanup()
@@ -809,8 +809,8 @@ func TestMailsBinds(t *testing.T) {
}
vm := goja.New()
- baseBinds(vm)
- mailsBinds(vm)
+ BindCore(vm)
+ BindMails(vm)
vm.Set("$app", app)
vm.Set("record", record)
@@ -845,17 +845,17 @@ func TestMailsBinds(t *testing.T) {
}
}
-func TestSecurityBindsCount(t *testing.T) {
+func TestBindSecurityCount(t *testing.T) {
vm := goja.New()
- securityBinds(vm)
+ BindSecurity(vm)
testBindsCount(vm, "$security", 16, t)
}
func TestSecurityCryptoBinds(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
- securityBinds(vm)
+ BindCore(vm)
+ BindSecurity(vm)
sceneraios := []struct {
js string
@@ -888,8 +888,8 @@ func TestSecurityCryptoBinds(t *testing.T) {
func TestSecurityRandomStringBinds(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
- securityBinds(vm)
+ BindCore(vm)
+ BindSecurity(vm)
sceneraios := []struct {
js string
@@ -964,8 +964,8 @@ func TestSecurityJWTBinds(t *testing.T) {
for _, s := range sceneraios {
t.Run(s.name, func(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
- securityBinds(vm)
+ BindCore(vm)
+ BindSecurity(vm)
_, err := vm.RunString(s.js)
if err != nil {
@@ -977,8 +977,8 @@ func TestSecurityJWTBinds(t *testing.T) {
func TestSecurityEncryptAndDecryptBinds(t *testing.T) {
vm := goja.New()
- baseBinds(vm)
- securityBinds(vm)
+ BindCore(vm)
+ BindSecurity(vm)
_, err := vm.RunString(`
const key = "abcdabcdabcdabcdabcdabcdabcdabcd"
@@ -996,7 +996,7 @@ func TestSecurityEncryptAndDecryptBinds(t *testing.T) {
}
}
-func TestFilesystemBinds(t *testing.T) {
+func TestBindFilesystem(t *testing.T) {
app, _ := tests.NewTestApp()
defer app.Cleanup()
@@ -1020,8 +1020,8 @@ func TestFilesystemBinds(t *testing.T) {
vm.Set("tmpDir", tmpDir)
vm.Set("testFile", filepath.Join(app.DataDir(), "data.db"))
vm.Set("baseURL", srv.URL)
- baseBinds(vm)
- filesystemBinds(vm)
+ BindCore(vm)
+ BindFilesystem(vm)
testBindsCount(vm, "$filesystem", 6, t)
@@ -1116,24 +1116,24 @@ func TestFilesystemBinds(t *testing.T) {
}
}
-func TestFormsBinds(t *testing.T) {
+func TestBindForms(t *testing.T) {
vm := goja.New()
- formsBinds(vm)
+ BindForms(vm)
testBindsCount(vm, "this", 4, t)
}
-func TestApisBindsCount(t *testing.T) {
+func TestBindApisCount(t *testing.T) {
vm := goja.New()
- apisBinds(vm)
+ BindApis(vm)
testBindsCount(vm, "this", 8, t)
testBindsCount(vm, "$apis", 11, t)
}
-func TestApisBindsApiError(t *testing.T) {
+func TestBindApisErrors(t *testing.T) {
vm := goja.New()
- apisBinds(vm)
+ BindApis(vm)
scenarios := []struct {
js string
@@ -1190,8 +1190,8 @@ func TestLoadingDynamicModel(t *testing.T) {
defer app.Cleanup()
vm := goja.New()
- baseBinds(vm)
- dbxBinds(vm)
+ BindCore(vm)
+ BindDbx(vm)
vm.Set("$app", app)
_, err := vm.RunString(`
@@ -1291,8 +1291,8 @@ func TestDynamicModelMapFieldCaching(t *testing.T) {
defer app.Cleanup()
vm := goja.New()
- baseBinds(vm)
- dbxBinds(vm)
+ BindCore(vm)
+ BindDbx(vm)
vm.Set("$app", app)
_, err := vm.RunString(`
@@ -1350,8 +1350,8 @@ func TestLoadingArrayOf(t *testing.T) {
defer app.Cleanup()
vm := goja.New()
- baseBinds(vm)
- dbxBinds(vm)
+ BindCore(vm)
+ BindDbx(vm)
vm.Set("$app", app)
_, err := vm.RunString(`
@@ -1391,18 +1391,18 @@ func TestLoadingArrayOf(t *testing.T) {
}
}
-func TestHttpClientBindsCount(t *testing.T) {
+func TestBindHttpClientCount(t *testing.T) {
app, _ := tests.NewTestApp()
defer app.Cleanup()
vm := goja.New()
- httpClientBinds(vm)
+ BindHttpClient(vm)
testBindsCount(vm, "this", 2, t) // + FormData
testBindsCount(vm, "$http", 1, t)
}
-func TestHttpClientBindsSend(t *testing.T) {
+func TestBindHttpClientSend(t *testing.T) {
t.Parallel()
// start a test server
@@ -1447,8 +1447,8 @@ func TestHttpClientBindsSend(t *testing.T) {
defer server.Close()
vm := goja.New()
- baseBinds(vm)
- httpClientBinds(vm)
+ BindCore(vm)
+ BindHttpClient(vm)
vm.Set("testURL", server.URL)
_, err := vm.RunString(`
@@ -1626,7 +1626,7 @@ func TestHooksBinds(t *testing.T) {
vmFactory := func() *goja.Runtime {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("$app", app)
vm.Set("result", result)
return vm
@@ -1712,7 +1712,7 @@ func TestHooksExceptionUnwrapping(t *testing.T) {
vmFactory := func() *goja.Runtime {
vm := goja.New()
- baseBinds(vm)
+ BindCore(vm)
vm.Set("$app", app)
vm.Set("goErr", goErr)
return vm
@@ -1766,8 +1766,8 @@ func TestRouterBinds(t *testing.T) {
vmFactory := func() *goja.Runtime {
vm := goja.New()
- baseBinds(vm)
- apisBinds(vm)
+ BindCore(vm)
+ BindApis(vm)
vm.Set("$app", app)
vm.Set("result", result)
return vm
@@ -1855,16 +1855,16 @@ func TestRouterBinds(t *testing.T) {
}
}
-func TestFilepathBindsCount(t *testing.T) {
+func TestBindFilepathCount(t *testing.T) {
vm := goja.New()
- filepathBinds(vm)
+ BindFilepath(vm)
testBindsCount(vm, "$filepath", 15, t)
}
-func TestOsBindsCount(t *testing.T) {
+func TestBindOsCount(t *testing.T) {
vm := goja.New()
- osBinds(vm)
+ BindOs(vm)
testBindsCount(vm, "$os", 20, t)
}
diff --git a/plugins/jsvm/internal/types/generated/types.d.ts b/plugins/jsvm/internal/types/generated/types.d.ts
index 52898b79..fff98a65 100644
--- a/plugins/jsvm/internal/types/generated/types.d.ts
+++ b/plugins/jsvm/internal/types/generated/types.d.ts
@@ -1,4 +1,4 @@
-// 1775386251
+// 1776520206
// GENERATED CODE - DO NOT MODIFY BY HAND
// -------------------------------------------------------------------
@@ -1948,8 +1948,8 @@ namespace os {
* than ReadFrom. This is used to permit ReadFrom to call io.Copy
* without leading to a recursive call to ReadFrom.
*/
- type _sqpeBfS = noReadFrom&File
- interface fileWithoutReadFrom extends _sqpeBfS {
+ type _suctCDC = noReadFrom&File
+ interface fileWithoutReadFrom extends _suctCDC {
}
interface File {
/**
@@ -1993,8 +1993,8 @@ namespace os {
* than WriteTo. This is used to permit WriteTo to call io.Copy
* without leading to a recursive call to WriteTo.
*/
- type _sEowvrW = noWriteTo&File
- interface fileWithoutWriteTo extends _sEowvrW {
+ type _stDWZwf = noWriteTo&File
+ interface fileWithoutWriteTo extends _stDWZwf {
}
interface File {
/**
@@ -2940,8 +2940,8 @@ namespace os {
*
* The methods of File are safe for concurrent use.
*/
- type _sUQXiYX = file
- interface File extends _sUQXiYX {
+ type _svIqMNy = file
+ interface File extends _svIqMNy {
}
/**
* A FileInfo describes a file and is returned by [Stat] and [Lstat].
@@ -2991,6 +2991,366 @@ namespace os {
}
}
+/**
+ * Package filepath implements utility routines for manipulating filename paths
+ * in a way compatible with the target operating system-defined file paths.
+ *
+ * The filepath package uses either forward slashes or backslashes,
+ * depending on the operating system. To process paths such as URLs
+ * that always use forward slashes regardless of the operating
+ * system, see the [path] package.
+ */
+namespace filepath {
+ interface match {
+ /**
+ * Match reports whether name matches the shell file name pattern.
+ * The pattern syntax is:
+ *
+ * ```
+ * pattern:
+ * { term }
+ * term:
+ * '*' matches any sequence of non-Separator characters
+ * '?' matches any single non-Separator character
+ * '[' [ '^' ] { character-range } ']'
+ * character class (must be non-empty)
+ * c matches character c (c != '*', '?', '\\', '[')
+ * '\\' c matches character c
+ *
+ * character-range:
+ * c matches character c (c != '\\', '-', ']')
+ * '\\' c matches character c
+ * lo '-' hi matches character c for lo <= c <= hi
+ * ```
+ *
+ * Match requires pattern to match all of name, not just a substring.
+ * The only possible returned error is [ErrBadPattern], when pattern
+ * is malformed.
+ *
+ * On Windows, escaping is disabled. Instead, '\\' is treated as
+ * path separator.
+ */
+ (pattern: string, name: string): boolean
+ }
+ interface glob {
+ /**
+ * Glob returns the names of all files matching pattern or nil
+ * if there is no matching file. The syntax of patterns is the same
+ * as in [Match]. The pattern may describe hierarchical names such as
+ * /usr/*\/bin/ed (assuming the [Separator] is '/').
+ *
+ * Glob ignores file system errors such as I/O errors reading directories.
+ * The only possible returned error is [ErrBadPattern], when pattern
+ * is malformed.
+ */
+ (pattern: string): Array
+ }
+ interface clean {
+ /**
+ * Clean returns the shortest path name equivalent to path
+ * by purely lexical processing. It applies the following rules
+ * iteratively until no further processing can be done:
+ *
+ * 1. Replace multiple [Separator] elements with a single one.
+ * 2. Eliminate each . path name element (the current directory).
+ * 3. Eliminate each inner .. path name element (the parent directory)
+ * ```
+ * along with the non-.. element that precedes it.
+ * ```
+ * 4. Eliminate .. elements that begin a rooted path:
+ * ```
+ * that is, replace "/.." by "/" at the beginning of a path,
+ * assuming Separator is '/'.
+ * ```
+ *
+ * The returned path ends in a slash only if it represents a root directory,
+ * such as "/" on Unix or `C:\` on Windows.
+ *
+ * Finally, any occurrences of slash are replaced by Separator.
+ *
+ * If the result of this process is an empty string, Clean
+ * returns the string ".".
+ *
+ * On Windows, Clean does not modify the volume name other than to replace
+ * occurrences of "/" with `\`.
+ * For example, Clean("//host/share/../x") returns `\\host\share\x`.
+ *
+ * See also Rob Pike, “Lexical File Names in Plan 9 or
+ * Getting Dot-Dot Right,”
+ * https://9p.io/sys/doc/lexnames.html
+ */
+ (path: string): string
+ }
+ interface isLocal {
+ /**
+ * IsLocal reports whether path, using lexical analysis only, has all of these properties:
+ *
+ * ```
+ * - is within the subtree rooted at the directory in which path is evaluated
+ * - is not an absolute path
+ * - is not empty
+ * - on Windows, is not a reserved name such as "NUL"
+ * ```
+ *
+ * If IsLocal(path) returns true, then
+ * Join(base, path) will always produce a path contained within base and
+ * Clean(path) will always produce an unrooted path with no ".." path elements.
+ *
+ * IsLocal is a purely lexical operation.
+ * In particular, it does not account for the effect of any symbolic links
+ * that may exist in the filesystem.
+ */
+ (path: string): boolean
+ }
+ interface localize {
+ /**
+ * Localize converts a slash-separated path into an operating system path.
+ * The input path must be a valid path as reported by [io/fs.ValidPath].
+ *
+ * Localize returns an error if the path cannot be represented by the operating system.
+ * For example, the path a\b is rejected on Windows, on which \ is a separator
+ * character and cannot be part of a filename.
+ *
+ * The path returned by Localize will always be local, as reported by IsLocal.
+ */
+ (path: string): string
+ }
+ interface toSlash {
+ /**
+ * ToSlash returns the result of replacing each separator character
+ * in path with a slash ('/') character. Multiple separators are
+ * replaced by multiple slashes.
+ */
+ (path: string): string
+ }
+ interface fromSlash {
+ /**
+ * FromSlash returns the result of replacing each slash ('/') character
+ * in path with a separator character. Multiple slashes are replaced
+ * by multiple separators.
+ *
+ * See also the Localize function, which converts a slash-separated path
+ * as used by the io/fs package to an operating system path.
+ */
+ (path: string): string
+ }
+ interface splitList {
+ /**
+ * SplitList splits a list of paths joined by the OS-specific [ListSeparator],
+ * usually found in PATH or GOPATH environment variables.
+ * Unlike strings.Split, SplitList returns an empty slice when passed an empty
+ * string.
+ */
+ (path: string): Array
+ }
+ interface split {
+ /**
+ * Split splits path immediately following the final [Separator],
+ * separating it into a directory and file name component.
+ * If there is no Separator in path, Split returns an empty dir
+ * and file set to path.
+ * The returned values have the property that path = dir+file.
+ */
+ (path: string): [string, string]
+ }
+ interface join {
+ /**
+ * Join joins any number of path elements into a single path,
+ * separating them with an OS specific [Separator]. Empty elements
+ * are ignored. The result is Cleaned. However, if the argument
+ * list is empty or all its elements are empty, Join returns
+ * an empty string.
+ * On Windows, the result will only be a UNC path if the first
+ * non-empty element is a UNC path.
+ */
+ (...elem: string[]): string
+ }
+ interface ext {
+ /**
+ * Ext returns the file name extension used by path.
+ * The extension is the suffix beginning at the final dot
+ * in the final element of path; it is empty if there is
+ * no dot.
+ */
+ (path: string): string
+ }
+ interface evalSymlinks {
+ /**
+ * EvalSymlinks returns the path name after the evaluation of any symbolic
+ * links.
+ * If path is relative the result will be relative to the current directory,
+ * unless one of the components is an absolute symbolic link.
+ * EvalSymlinks calls [Clean] on the result.
+ */
+ (path: string): string
+ }
+ interface isAbs {
+ /**
+ * IsAbs reports whether the path is absolute.
+ */
+ (path: string): boolean
+ }
+ interface abs {
+ /**
+ * Abs returns an absolute representation of path.
+ * If the path is not absolute it will be joined with the current
+ * working directory to turn it into an absolute path. The absolute
+ * path name for a given file is not guaranteed to be unique.
+ * Abs calls [Clean] on the result.
+ */
+ (path: string): string
+ }
+ interface rel {
+ /**
+ * Rel returns a relative path that is lexically equivalent to targpath when
+ * joined to basepath with an intervening separator. That is,
+ * [Join](basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
+ * On success, the returned path will always be relative to basepath,
+ * even if basepath and targpath share no elements.
+ * An error is returned if targpath can't be made relative to basepath or if
+ * knowing the current working directory would be necessary to compute it.
+ * Rel calls [Clean] on the result.
+ */
+ (basepath: string, targpath: string): string
+ }
+ /**
+ * WalkFunc is the type of the function called by [Walk] to visit each
+ * file or directory.
+ *
+ * The path argument contains the argument to Walk as a prefix.
+ * That is, if Walk is called with root argument "dir" and finds a file
+ * named "a" in that directory, the walk function will be called with
+ * argument "dir/a".
+ *
+ * The directory and file are joined with Join, which may clean the
+ * directory name: if Walk is called with the root argument "x/../dir"
+ * and finds a file named "a" in that directory, the walk function will
+ * be called with argument "dir/a", not "x/../dir/a".
+ *
+ * The info argument is the fs.FileInfo for the named path.
+ *
+ * The error result returned by the function controls how Walk continues.
+ * If the function returns the special value [SkipDir], Walk skips the
+ * current directory (path if info.IsDir() is true, otherwise path's
+ * parent directory). If the function returns the special value [SkipAll],
+ * Walk skips all remaining files and directories. Otherwise, if the function
+ * returns a non-nil error, Walk stops entirely and returns that error.
+ *
+ * The err argument reports an error related to path, signaling that Walk
+ * will not walk into that directory. The function can decide how to
+ * handle that error; as described earlier, returning the error will
+ * cause Walk to stop walking the entire tree.
+ *
+ * Walk calls the function with a non-nil err argument in two cases.
+ *
+ * First, if an [os.Lstat] on the root directory or any directory or file
+ * in the tree fails, Walk calls the function with path set to that
+ * directory or file's path, info set to nil, and err set to the error
+ * from os.Lstat.
+ *
+ * Second, if a directory's Readdirnames method fails, Walk calls the
+ * function with path set to the directory's path, info, set to an
+ * [fs.FileInfo] describing the directory, and err set to the error from
+ * Readdirnames.
+ */
+ interface WalkFunc {(path: string, info: fs.FileInfo, err: Error): void }
+ interface walkDir {
+ /**
+ * WalkDir walks the file tree rooted at root, calling fn for each file or
+ * directory in the tree, including root.
+ *
+ * All errors that arise visiting files and directories are filtered by fn:
+ * see the [fs.WalkDirFunc] documentation for details.
+ *
+ * The files are walked in lexical order, which makes the output deterministic
+ * but requires WalkDir to read an entire directory into memory before proceeding
+ * to walk that directory.
+ *
+ * WalkDir does not follow symbolic links.
+ *
+ * WalkDir calls fn with paths that use the separator character appropriate
+ * for the operating system. This is unlike [io/fs.WalkDir], which always
+ * uses slash separated paths.
+ */
+ (root: string, fn: fs.WalkDirFunc): void
+ }
+ interface walk {
+ /**
+ * Walk walks the file tree rooted at root, calling fn for each file or
+ * directory in the tree, including root.
+ *
+ * All errors that arise visiting files and directories are filtered by fn:
+ * see the [WalkFunc] documentation for details.
+ *
+ * The files are walked in lexical order, which makes the output deterministic
+ * but requires Walk to read an entire directory into memory before proceeding
+ * to walk that directory.
+ *
+ * Walk does not follow symbolic links.
+ *
+ * Walk is less efficient than [WalkDir], introduced in Go 1.16,
+ * which avoids calling os.Lstat on every visited file or directory.
+ */
+ (root: string, fn: WalkFunc): void
+ }
+ interface base {
+ /**
+ * Base returns the last element of path.
+ * Trailing path separators are removed before extracting the last element.
+ * If the path is empty, Base returns ".".
+ * If the path consists entirely of separators, Base returns a single separator.
+ */
+ (path: string): string
+ }
+ interface dir {
+ /**
+ * Dir returns all but the last element of path, typically the path's directory.
+ * After dropping the final element, Dir calls [Clean] on the path and trailing
+ * slashes are removed.
+ * If the path is empty, Dir returns ".".
+ * If the path consists entirely of separators, Dir returns a single separator.
+ * The returned path does not end in a separator unless it is the root directory.
+ */
+ (path: string): string
+ }
+ interface volumeName {
+ /**
+ * VolumeName returns leading volume name.
+ * Given "C:\foo\bar" it returns "C:" on Windows.
+ * Given "\\host\share\foo" it returns "\\host\share".
+ * On other platforms it returns "".
+ */
+ (path: string): string
+ }
+ interface hasPrefix {
+ /**
+ * HasPrefix exists for historical compatibility and should not be used.
+ *
+ * Deprecated: HasPrefix does not respect path boundaries and
+ * does not ignore case when required.
+ */
+ (p: string, prefix: string): boolean
+ }
+}
+
+/**
+ * Package validation provides configurable and extensible rules for validating data of various types.
+ */
+namespace ozzo_validation {
+ /**
+ * Error interface represents an validation error
+ */
+ interface Error {
+ [key:string]: any;
+ error(): string
+ code(): string
+ message(): string
+ setMessage(_arg0: string): Error
+ params(): _TygojaDict
+ setParams(_arg0: _TygojaDict): Error
+ }
+}
+
/**
* Package dbx provides a set of DB-agnostic and easy-to-use query building methods for relational databases.
*/
@@ -3327,14 +3687,14 @@ namespace dbx {
/**
* MssqlBuilder is the builder for SQL Server databases.
*/
- type _sCHEhNd = BaseBuilder
- interface MssqlBuilder extends _sCHEhNd {
+ type _sHLDdri = BaseBuilder
+ interface MssqlBuilder extends _sHLDdri {
}
/**
* MssqlQueryBuilder is the query builder for SQL Server databases.
*/
- type _sUjmedL = BaseQueryBuilder
- interface MssqlQueryBuilder extends _sUjmedL {
+ type _sWCeSkQ = BaseQueryBuilder
+ interface MssqlQueryBuilder extends _sWCeSkQ {
}
interface newMssqlBuilder {
/**
@@ -3405,8 +3765,8 @@ namespace dbx {
/**
* MysqlBuilder is the builder for MySQL databases.
*/
- type _sSFtjLm = BaseBuilder
- interface MysqlBuilder extends _sSFtjLm {
+ type _sJqClKK = BaseBuilder
+ interface MysqlBuilder extends _sJqClKK {
}
interface newMysqlBuilder {
/**
@@ -3481,14 +3841,14 @@ namespace dbx {
/**
* OciBuilder is the builder for Oracle databases.
*/
- type _sCYaXFI = BaseBuilder
- interface OciBuilder extends _sCYaXFI {
+ type _stzmBoy = BaseBuilder
+ interface OciBuilder extends _stzmBoy {
}
/**
* OciQueryBuilder is the query builder for Oracle databases.
*/
- type _sLcNFEh = BaseQueryBuilder
- interface OciQueryBuilder extends _sLcNFEh {
+ type _sjGRsll = BaseQueryBuilder
+ interface OciQueryBuilder extends _sjGRsll {
}
interface newOciBuilder {
/**
@@ -3551,8 +3911,8 @@ namespace dbx {
/**
* PgsqlBuilder is the builder for PostgreSQL databases.
*/
- type _suaFvTr = BaseBuilder
- interface PgsqlBuilder extends _suaFvTr {
+ type _sePvgMC = BaseBuilder
+ interface PgsqlBuilder extends _sePvgMC {
}
interface newPgsqlBuilder {
/**
@@ -3619,8 +3979,8 @@ namespace dbx {
/**
* SqliteQueryBuilder is the query builder for SQLite databases.
*/
- type _spXNsOQ = BaseQueryBuilder
- interface SqliteQueryBuilder extends _spXNsOQ {
+ type _sDukgXi = BaseQueryBuilder
+ interface SqliteQueryBuilder extends _sDukgXi {
}
interface SqliteQueryBuilder {
/**
@@ -3641,8 +4001,8 @@ namespace dbx {
/**
* SqliteBuilder is the builder for SQLite databases.
*/
- type _sibotlw = BaseBuilder
- interface SqliteBuilder extends _sibotlw {
+ type _sbnzcXy = BaseBuilder
+ interface SqliteBuilder extends _sbnzcXy {
}
interface newSqliteBuilder {
/**
@@ -3741,8 +4101,8 @@ namespace dbx {
/**
* StandardBuilder is the builder that is used by DB for an unknown driver.
*/
- type _syRszNu = BaseBuilder
- interface StandardBuilder extends _syRszNu {
+ type _sgnvzTj = BaseBuilder
+ interface StandardBuilder extends _sgnvzTj {
}
interface newStandardBuilder {
/**
@@ -3808,8 +4168,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 _sNsFARL = Builder
- interface DB extends _sNsFARL {
+ type _ssRtHfn = Builder
+ interface DB extends _ssRtHfn {
/**
* FieldMapper maps struct fields to DB columns. Defaults to DefaultFieldMapFunc.
*/
@@ -4639,8 +4999,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 _sDlLhRs = sql.Rows
- interface Rows extends _sDlLhRs {
+ type _sWZmqAq = sql.Rows
+ interface Rows extends _sWZmqAq {
}
interface Rows {
/**
@@ -5015,8 +5375,8 @@ namespace dbx {
}): string }
interface structInfo {
}
- type _sMdGugf = structInfo
- interface structValue extends _sMdGugf {
+ type _siCTHGT = structInfo
+ interface structValue extends _siCTHGT {
}
interface fieldInfo {
}
@@ -5055,8 +5415,8 @@ namespace dbx {
/**
* Tx enhances sql.Tx with additional querying methods.
*/
- type _sliGPQb = Builder
- interface Tx extends _sliGPQb {
+ type _siOcSEO = Builder
+ interface Tx extends _siOcSEO {
}
interface Tx {
/**
@@ -5072,348 +5432,6 @@ namespace dbx {
}
}
-/**
- * Package filepath implements utility routines for manipulating filename paths
- * in a way compatible with the target operating system-defined file paths.
- *
- * The filepath package uses either forward slashes or backslashes,
- * depending on the operating system. To process paths such as URLs
- * that always use forward slashes regardless of the operating
- * system, see the [path] package.
- */
-namespace filepath {
- interface match {
- /**
- * Match reports whether name matches the shell file name pattern.
- * The pattern syntax is:
- *
- * ```
- * pattern:
- * { term }
- * term:
- * '*' matches any sequence of non-Separator characters
- * '?' matches any single non-Separator character
- * '[' [ '^' ] { character-range } ']'
- * character class (must be non-empty)
- * c matches character c (c != '*', '?', '\\', '[')
- * '\\' c matches character c
- *
- * character-range:
- * c matches character c (c != '\\', '-', ']')
- * '\\' c matches character c
- * lo '-' hi matches character c for lo <= c <= hi
- * ```
- *
- * Match requires pattern to match all of name, not just a substring.
- * The only possible returned error is [ErrBadPattern], when pattern
- * is malformed.
- *
- * On Windows, escaping is disabled. Instead, '\\' is treated as
- * path separator.
- */
- (pattern: string, name: string): boolean
- }
- interface glob {
- /**
- * Glob returns the names of all files matching pattern or nil
- * if there is no matching file. The syntax of patterns is the same
- * as in [Match]. The pattern may describe hierarchical names such as
- * /usr/*\/bin/ed (assuming the [Separator] is '/').
- *
- * Glob ignores file system errors such as I/O errors reading directories.
- * The only possible returned error is [ErrBadPattern], when pattern
- * is malformed.
- */
- (pattern: string): Array
- }
- interface clean {
- /**
- * Clean returns the shortest path name equivalent to path
- * by purely lexical processing. It applies the following rules
- * iteratively until no further processing can be done:
- *
- * 1. Replace multiple [Separator] elements with a single one.
- * 2. Eliminate each . path name element (the current directory).
- * 3. Eliminate each inner .. path name element (the parent directory)
- * ```
- * along with the non-.. element that precedes it.
- * ```
- * 4. Eliminate .. elements that begin a rooted path:
- * ```
- * that is, replace "/.." by "/" at the beginning of a path,
- * assuming Separator is '/'.
- * ```
- *
- * The returned path ends in a slash only if it represents a root directory,
- * such as "/" on Unix or `C:\` on Windows.
- *
- * Finally, any occurrences of slash are replaced by Separator.
- *
- * If the result of this process is an empty string, Clean
- * returns the string ".".
- *
- * On Windows, Clean does not modify the volume name other than to replace
- * occurrences of "/" with `\`.
- * For example, Clean("//host/share/../x") returns `\\host\share\x`.
- *
- * See also Rob Pike, “Lexical File Names in Plan 9 or
- * Getting Dot-Dot Right,”
- * https://9p.io/sys/doc/lexnames.html
- */
- (path: string): string
- }
- interface isLocal {
- /**
- * IsLocal reports whether path, using lexical analysis only, has all of these properties:
- *
- * ```
- * - is within the subtree rooted at the directory in which path is evaluated
- * - is not an absolute path
- * - is not empty
- * - on Windows, is not a reserved name such as "NUL"
- * ```
- *
- * If IsLocal(path) returns true, then
- * Join(base, path) will always produce a path contained within base and
- * Clean(path) will always produce an unrooted path with no ".." path elements.
- *
- * IsLocal is a purely lexical operation.
- * In particular, it does not account for the effect of any symbolic links
- * that may exist in the filesystem.
- */
- (path: string): boolean
- }
- interface localize {
- /**
- * Localize converts a slash-separated path into an operating system path.
- * The input path must be a valid path as reported by [io/fs.ValidPath].
- *
- * Localize returns an error if the path cannot be represented by the operating system.
- * For example, the path a\b is rejected on Windows, on which \ is a separator
- * character and cannot be part of a filename.
- *
- * The path returned by Localize will always be local, as reported by IsLocal.
- */
- (path: string): string
- }
- interface toSlash {
- /**
- * ToSlash returns the result of replacing each separator character
- * in path with a slash ('/') character. Multiple separators are
- * replaced by multiple slashes.
- */
- (path: string): string
- }
- interface fromSlash {
- /**
- * FromSlash returns the result of replacing each slash ('/') character
- * in path with a separator character. Multiple slashes are replaced
- * by multiple separators.
- *
- * See also the Localize function, which converts a slash-separated path
- * as used by the io/fs package to an operating system path.
- */
- (path: string): string
- }
- interface splitList {
- /**
- * SplitList splits a list of paths joined by the OS-specific [ListSeparator],
- * usually found in PATH or GOPATH environment variables.
- * Unlike strings.Split, SplitList returns an empty slice when passed an empty
- * string.
- */
- (path: string): Array
- }
- interface split {
- /**
- * Split splits path immediately following the final [Separator],
- * separating it into a directory and file name component.
- * If there is no Separator in path, Split returns an empty dir
- * and file set to path.
- * The returned values have the property that path = dir+file.
- */
- (path: string): [string, string]
- }
- interface join {
- /**
- * Join joins any number of path elements into a single path,
- * separating them with an OS specific [Separator]. Empty elements
- * are ignored. The result is Cleaned. However, if the argument
- * list is empty or all its elements are empty, Join returns
- * an empty string.
- * On Windows, the result will only be a UNC path if the first
- * non-empty element is a UNC path.
- */
- (...elem: string[]): string
- }
- interface ext {
- /**
- * Ext returns the file name extension used by path.
- * The extension is the suffix beginning at the final dot
- * in the final element of path; it is empty if there is
- * no dot.
- */
- (path: string): string
- }
- interface evalSymlinks {
- /**
- * EvalSymlinks returns the path name after the evaluation of any symbolic
- * links.
- * If path is relative the result will be relative to the current directory,
- * unless one of the components is an absolute symbolic link.
- * EvalSymlinks calls [Clean] on the result.
- */
- (path: string): string
- }
- interface isAbs {
- /**
- * IsAbs reports whether the path is absolute.
- */
- (path: string): boolean
- }
- interface abs {
- /**
- * Abs returns an absolute representation of path.
- * If the path is not absolute it will be joined with the current
- * working directory to turn it into an absolute path. The absolute
- * path name for a given file is not guaranteed to be unique.
- * Abs calls [Clean] on the result.
- */
- (path: string): string
- }
- interface rel {
- /**
- * Rel returns a relative path that is lexically equivalent to targpath when
- * joined to basepath with an intervening separator. That is,
- * [Join](basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
- * On success, the returned path will always be relative to basepath,
- * even if basepath and targpath share no elements.
- * An error is returned if targpath can't be made relative to basepath or if
- * knowing the current working directory would be necessary to compute it.
- * Rel calls [Clean] on the result.
- */
- (basepath: string, targpath: string): string
- }
- /**
- * WalkFunc is the type of the function called by [Walk] to visit each
- * file or directory.
- *
- * The path argument contains the argument to Walk as a prefix.
- * That is, if Walk is called with root argument "dir" and finds a file
- * named "a" in that directory, the walk function will be called with
- * argument "dir/a".
- *
- * The directory and file are joined with Join, which may clean the
- * directory name: if Walk is called with the root argument "x/../dir"
- * and finds a file named "a" in that directory, the walk function will
- * be called with argument "dir/a", not "x/../dir/a".
- *
- * The info argument is the fs.FileInfo for the named path.
- *
- * The error result returned by the function controls how Walk continues.
- * If the function returns the special value [SkipDir], Walk skips the
- * current directory (path if info.IsDir() is true, otherwise path's
- * parent directory). If the function returns the special value [SkipAll],
- * Walk skips all remaining files and directories. Otherwise, if the function
- * returns a non-nil error, Walk stops entirely and returns that error.
- *
- * The err argument reports an error related to path, signaling that Walk
- * will not walk into that directory. The function can decide how to
- * handle that error; as described earlier, returning the error will
- * cause Walk to stop walking the entire tree.
- *
- * Walk calls the function with a non-nil err argument in two cases.
- *
- * First, if an [os.Lstat] on the root directory or any directory or file
- * in the tree fails, Walk calls the function with path set to that
- * directory or file's path, info set to nil, and err set to the error
- * from os.Lstat.
- *
- * Second, if a directory's Readdirnames method fails, Walk calls the
- * function with path set to the directory's path, info, set to an
- * [fs.FileInfo] describing the directory, and err set to the error from
- * Readdirnames.
- */
- interface WalkFunc {(path: string, info: fs.FileInfo, err: Error): void }
- interface walkDir {
- /**
- * WalkDir walks the file tree rooted at root, calling fn for each file or
- * directory in the tree, including root.
- *
- * All errors that arise visiting files and directories are filtered by fn:
- * see the [fs.WalkDirFunc] documentation for details.
- *
- * The files are walked in lexical order, which makes the output deterministic
- * but requires WalkDir to read an entire directory into memory before proceeding
- * to walk that directory.
- *
- * WalkDir does not follow symbolic links.
- *
- * WalkDir calls fn with paths that use the separator character appropriate
- * for the operating system. This is unlike [io/fs.WalkDir], which always
- * uses slash separated paths.
- */
- (root: string, fn: fs.WalkDirFunc): void
- }
- interface walk {
- /**
- * Walk walks the file tree rooted at root, calling fn for each file or
- * directory in the tree, including root.
- *
- * All errors that arise visiting files and directories are filtered by fn:
- * see the [WalkFunc] documentation for details.
- *
- * The files are walked in lexical order, which makes the output deterministic
- * but requires Walk to read an entire directory into memory before proceeding
- * to walk that directory.
- *
- * Walk does not follow symbolic links.
- *
- * Walk is less efficient than [WalkDir], introduced in Go 1.16,
- * which avoids calling os.Lstat on every visited file or directory.
- */
- (root: string, fn: WalkFunc): void
- }
- interface base {
- /**
- * Base returns the last element of path.
- * Trailing path separators are removed before extracting the last element.
- * If the path is empty, Base returns ".".
- * If the path consists entirely of separators, Base returns a single separator.
- */
- (path: string): string
- }
- interface dir {
- /**
- * Dir returns all but the last element of path, typically the path's directory.
- * After dropping the final element, Dir calls [Clean] on the path and trailing
- * slashes are removed.
- * If the path is empty, Dir returns ".".
- * If the path consists entirely of separators, Dir returns a single separator.
- * The returned path does not end in a separator unless it is the root directory.
- */
- (path: string): string
- }
- interface volumeName {
- /**
- * VolumeName returns leading volume name.
- * Given "C:\foo\bar" it returns "C:" on Windows.
- * Given "\\host\share\foo" it returns "\\host\share".
- * On other platforms it returns "".
- */
- (path: string): string
- }
- interface hasPrefix {
- /**
- * HasPrefix exists for historical compatibility and should not be used.
- *
- * Deprecated: HasPrefix does not respect path boundaries and
- * does not ignore case when required.
- */
- (p: string, prefix: string): boolean
- }
-}
-
namespace security {
interface s256Challenge {
/**
@@ -5557,129 +5575,6 @@ namespace security {
}
}
-/**
- * Package template is a thin wrapper around the standard html/template
- * and text/template packages that implements a convenient registry to
- * load and cache templates on the fly concurrently.
- *
- * It was created to assist the JSVM plugin HTML rendering, but could be used in other Go code.
- *
- * Example:
- *
- * ```
- * registry := template.NewRegistry()
- *
- * html1, err := registry.LoadFiles(
- * // the files set wil be parsed only once and then cached
- * "layout.html",
- * "content.html",
- * ).Render(map[string]any{"name": "John"})
- *
- * html2, err := registry.LoadFiles(
- * // reuse the already parsed and cached files set
- * "layout.html",
- * "content.html",
- * ).Render(map[string]any{"name": "Jane"})
- * ```
- */
-namespace template {
- interface newRegistry {
- /**
- * NewRegistry creates and initializes a new templates registry with
- * some defaults (eg. global "raw" template function for unescaped HTML).
- *
- * Use the Registry.Load* methods to load templates into the registry.
- */
- (): (Registry)
- }
- /**
- * Registry defines a templates registry that is safe to be used by multiple goroutines.
- *
- * Use the Registry.Load* methods to load templates into the registry.
- */
- interface Registry {
- }
- interface Registry {
- /**
- * AddFuncs registers new global template functions.
- *
- * The key of each map entry is the function name that will be used in the templates.
- * If a function with the map entry name already exists it will be replaced with the new one.
- *
- * The value of each map entry is a function that must have either a
- * single return value, or two return values of which the second has type error.
- *
- * Example:
- *
- * ```
- * r.AddFuncs(map[string]any{
- * "toUpper": func(str string) string {
- * return strings.ToUppser(str)
- * },
- * ...
- * })
- * ```
- */
- addFuncs(funcs: _TygojaDict): (Registry)
- }
- interface Registry {
- /**
- * LoadFiles caches (if not already) the specified filenames set as a
- * single template and returns a ready to use Renderer instance.
- *
- * There must be at least 1 filename specified.
- */
- loadFiles(...filenames: string[]): (Renderer)
- }
- interface Registry {
- /**
- * LoadString caches (if not already) the specified inline string as a
- * single template and returns a ready to use Renderer instance.
- */
- loadString(text: string): (Renderer)
- }
- interface Registry {
- /**
- * LoadFS caches (if not already) the specified fs and globPatterns
- * pair as single template and returns a ready to use Renderer instance.
- *
- * There must be at least 1 file matching the provided globPattern(s)
- * (note that most file names serves as glob patterns matching themselves).
- */
- loadFS(fsys: fs.FS, ...globPatterns: string[]): (Renderer)
- }
- /**
- * Renderer defines a single parsed template.
- */
- interface Renderer {
- }
- interface Renderer {
- /**
- * Render executes the template with the specified data as the dot object
- * and returns the result as plain string.
- */
- render(data: any): string
- }
-}
-
-/**
- * Package validation provides configurable and extensible rules for validating data of various types.
- */
-namespace ozzo_validation {
- /**
- * Error interface represents an validation error
- */
- interface Error {
- [key:string]: any;
- error(): string
- code(): string
- message(): string
- setMessage(_arg0: string): Error
- params(): _TygojaDict
- setParams(_arg0: _TygojaDict): Error
- }
-}
-
namespace filesystem {
/**
* FileReader defines an interface for a file resource reader.
@@ -5776,8 +5671,8 @@ namespace filesystem {
*/
open(): io.ReadSeekCloser
}
- type _sXCJRsA = bytes.Reader
- interface bytesReadSeekCloser extends _sXCJRsA {
+ type _sUikSqo = bytes.Reader
+ interface bytesReadSeekCloser extends _sUikSqo {
}
interface bytesReadSeekCloser {
/**
@@ -5961,6 +5856,111 @@ namespace filesystem {
}
}
+/**
+ * Package template is a thin wrapper around the standard html/template
+ * and text/template packages that implements a convenient registry to
+ * load and cache templates on the fly concurrently.
+ *
+ * It was created to assist the JSVM plugin HTML rendering, but could be used in other Go code.
+ *
+ * Example:
+ *
+ * ```
+ * registry := template.NewRegistry()
+ *
+ * html1, err := registry.LoadFiles(
+ * // the files set wil be parsed only once and then cached
+ * "layout.html",
+ * "content.html",
+ * ).Render(map[string]any{"name": "John"})
+ *
+ * html2, err := registry.LoadFiles(
+ * // reuse the already parsed and cached files set
+ * "layout.html",
+ * "content.html",
+ * ).Render(map[string]any{"name": "Jane"})
+ * ```
+ */
+namespace template {
+ interface newRegistry {
+ /**
+ * NewRegistry creates and initializes a new templates registry with
+ * some defaults (eg. global "raw" template function for unescaped HTML).
+ *
+ * Use the Registry.Load* methods to load templates into the registry.
+ */
+ (): (Registry)
+ }
+ /**
+ * Registry defines a templates registry that is safe to be used by multiple goroutines.
+ *
+ * Use the Registry.Load* methods to load templates into the registry.
+ */
+ interface Registry {
+ }
+ interface Registry {
+ /**
+ * AddFuncs registers new global template functions.
+ *
+ * The key of each map entry is the function name that will be used in the templates.
+ * If a function with the map entry name already exists it will be replaced with the new one.
+ *
+ * The value of each map entry is a function that must have either a
+ * single return value, or two return values of which the second has type error.
+ *
+ * Example:
+ *
+ * ```
+ * r.AddFuncs(map[string]any{
+ * "toUpper": func(str string) string {
+ * return strings.ToUppser(str)
+ * },
+ * ...
+ * })
+ * ```
+ */
+ addFuncs(funcs: _TygojaDict): (Registry)
+ }
+ interface Registry {
+ /**
+ * LoadFiles caches (if not already) the specified filenames set as a
+ * single template and returns a ready to use Renderer instance.
+ *
+ * There must be at least 1 filename specified.
+ */
+ loadFiles(...filenames: string[]): (Renderer)
+ }
+ interface Registry {
+ /**
+ * LoadString caches (if not already) the specified inline string as a
+ * single template and returns a ready to use Renderer instance.
+ */
+ loadString(text: string): (Renderer)
+ }
+ interface Registry {
+ /**
+ * LoadFS caches (if not already) the specified fs and globPatterns
+ * pair as single template and returns a ready to use Renderer instance.
+ *
+ * There must be at least 1 file matching the provided globPattern(s)
+ * (note that most file names serves as glob patterns matching themselves).
+ */
+ loadFS(fsys: fs.FS, ...globPatterns: string[]): (Renderer)
+ }
+ /**
+ * Renderer defines a single parsed template.
+ */
+ interface Renderer {
+ }
+ interface Renderer {
+ /**
+ * Render executes the template with the specified data as the dot object
+ * and returns the result as plain string.
+ */
+ render(data: any): string
+ }
+}
+
/**
* Package exec runs external commands. It wraps os.StartProcess to make it
* easier to remap stdin and stdout, connect I/O with pipes, and do other
@@ -6381,6 +6381,16 @@ namespace core {
* "dangerousSelectQuery" argument must come only from trusted input!
*/
createViewFields(dangerousSelectQuery: string): FieldsList
+ /**
+ * DryRunView executes the provided query by creating a temporary view
+ * collection and returning a sample of the resulting query records (if valid).
+ *
+ * The same caveats from CreateViewFields apply here too.
+ *
+ * NB! Be aware that this method is vulnerable to SQL injection and the
+ * "dangerousSelectQuery" argument must come only from trusted input!
+ */
+ dryRunView(dangerousSelectQuery: string, sampleSize: number): (DryRunViewResult)
/**
* FindRecordByViewFile returns the original Record of the provided view collection file.
*/
@@ -7745,8 +7755,8 @@ namespace core {
/**
* AuthOrigin defines a Record proxy for working with the authOrigins collection.
*/
- type _sHgvaxY = Record
- interface AuthOrigin extends _sHgvaxY {
+ type _scTBnOT = Record
+ interface AuthOrigin extends _scTBnOT {
}
interface newAuthOrigin {
/**
@@ -8491,8 +8501,8 @@ namespace core {
/**
* @todo experiment eventually replacing the rules *string with a struct?
*/
- type _sGzXAzW = BaseModel
- interface baseCollection extends _sGzXAzW {
+ type _sDHXMrV = BaseModel
+ interface baseCollection extends _sDHXMrV {
listRule?: string
viewRule?: string
createRule?: string
@@ -8519,8 +8529,8 @@ namespace core {
/**
* Collection defines the table, fields and various options related to a set of records.
*/
- type _sRMHUSX = baseCollection&collectionAuthOptions&collectionViewOptions
- interface Collection extends _sRMHUSX {
+ type _sSFIpTf = baseCollection&collectionAuthOptions&collectionViewOptions
+ interface Collection extends _sSFIpTf {
}
interface newCollection {
/**
@@ -9530,8 +9540,8 @@ namespace core {
/**
* RequestEvent defines the PocketBase router handler event.
*/
- type _seycyrn = router.Event
- interface RequestEvent extends _seycyrn {
+ type _sFNHWWc = router.Event
+ interface RequestEvent extends _sFNHWWc {
app: App
auth?: Record
}
@@ -9591,8 +9601,8 @@ namespace core {
*/
clone(): (RequestInfo)
}
- type _sOHvNTa = hook.Event&RequestEvent
- interface BatchRequestEvent extends _sOHvNTa {
+ type _smofDkV = hook.Event&RequestEvent
+ interface BatchRequestEvent extends _smofDkV {
batch: Array<(InternalRequest | undefined)>
}
interface InternalRequest {
@@ -9627,26 +9637,31 @@ namespace core {
collection?: Collection
}
interface baseCollectionEventData {
+ /**
+ * @todo consider storing the original collection name and use that as a tag
+ * to avoid the ambiguity when the collection is being modified (#7613);
+ * for new collection also maybe return empty tags?
+ */
tags(): Array
}
- type _sBLZMfk = hook.Event
- interface BootstrapEvent extends _sBLZMfk {
+ type _sAkfpmx = hook.Event
+ interface BootstrapEvent extends _sAkfpmx {
app: App
}
- type _sKvnHjI = hook.Event
- interface TerminateEvent extends _sKvnHjI {
+ type _smyBnni = hook.Event
+ interface TerminateEvent extends _smyBnni {
app: App
isRestart: boolean
}
- type _syHyPDy = hook.Event
- interface BackupEvent extends _syHyPDy {
+ type _ssgtYuq = hook.Event
+ interface BackupEvent extends _ssgtYuq {
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 _scSvdOO = hook.Event
- interface ServeEvent extends _scSvdOO {
+ type _siNDrxi = hook.Event
+ interface ServeEvent extends _siNDrxi {
app: App
router?: router.Router
server?: http.Server
@@ -9674,32 +9689,50 @@ namespace core {
* Set it to nil if you want to skip the installer.
*/
installerFunc: (app: App, systemSuperuser: Record, baseURL: string) => void
+ /**
+ * @todo experimental
+ *
+ * UIExtensions is a list with the superuser UI extensions.
+ */
+ uiExtensions: Array
}
- type _suSufTZ = hook.Event&RequestEvent
- interface SettingsListRequestEvent extends _suSufTZ {
+ interface UIExtension {
+ /**
+ * Name is the name of the extension.
+ * It is also used as path segment for the registered public extension endpoint
+ * (e.g. /_/extensions/{name}/*)
+ */
+ name: string
+ /**
+ * FS is the extension file system.
+ */
+ fs: fs.FS
+ }
+ type _sGUGxGZ = hook.Event&RequestEvent
+ interface SettingsListRequestEvent extends _sGUGxGZ {
settings?: Settings
}
- type _sxqhtjV = hook.Event&RequestEvent
- interface SettingsUpdateRequestEvent extends _sxqhtjV {
+ type _sEjvJpz = hook.Event&RequestEvent
+ interface SettingsUpdateRequestEvent extends _sEjvJpz {
oldSettings?: Settings
newSettings?: Settings
}
- type _sQkYwSD = hook.Event
- interface SettingsReloadEvent extends _sQkYwSD {
+ type _sspkPjA = hook.Event
+ interface SettingsReloadEvent extends _sspkPjA {
app: App
}
- type _szuLVQN = hook.Event
- interface MailerEvent extends _szuLVQN {
+ type _sNOucYl = hook.Event
+ interface MailerEvent extends _sNOucYl {
app: App
mailer: mailer.Mailer
message?: mailer.Message
}
- type _sHLpKGI = MailerEvent&baseRecordEventData
- interface MailerRecordEvent extends _sHLpKGI {
+ type _sHgQkKL = MailerEvent&baseRecordEventData
+ interface MailerRecordEvent extends _sHgQkKL {
meta: _TygojaDict
}
- type _sHLjwEy = hook.Event&baseModelEventData
- interface ModelEvent extends _sHLjwEy {
+ type _sLWDXqg = hook.Event&baseModelEventData
+ interface ModelEvent extends _sLWDXqg {
app: App
context: context.Context
/**
@@ -9711,12 +9744,12 @@ namespace core {
*/
type: string
}
- type _sTPjoLw = ModelEvent
- interface ModelErrorEvent extends _sTPjoLw {
+ type _srZFIWq = ModelEvent
+ interface ModelErrorEvent extends _srZFIWq {
error: Error
}
- type _sREDOmz = hook.Event&baseRecordEventData
- interface RecordEvent extends _sREDOmz {
+ type _sLufonV = hook.Event&baseRecordEventData
+ interface RecordEvent extends _sLufonV {
app: App
context: context.Context
/**
@@ -9728,12 +9761,12 @@ namespace core {
*/
type: string
}
- type _sGIIrIs = RecordEvent
- interface RecordErrorEvent extends _sGIIrIs {
+ type _sBSuaAd = RecordEvent
+ interface RecordErrorEvent extends _sBSuaAd {
error: Error
}
- type _sTJeDts = hook.Event&baseCollectionEventData
- interface CollectionEvent extends _sTJeDts {
+ type _sHQGeaJ = hook.Event&baseCollectionEventData
+ interface CollectionEvent extends _sHQGeaJ {
app: App
context: context.Context
/**
@@ -9745,16 +9778,16 @@ namespace core {
*/
type: string
}
- type _sDAdXzH = CollectionEvent
- interface CollectionErrorEvent extends _sDAdXzH {
+ type _sQePZIo = CollectionEvent
+ interface CollectionErrorEvent extends _sQePZIo {
error: Error
}
- type _sSsDuFH = hook.Event&RequestEvent&baseRecordEventData
- interface FileTokenRequestEvent extends _sSsDuFH {
+ type _sTXaTCY = hook.Event&RequestEvent&baseRecordEventData
+ interface FileTokenRequestEvent extends _sTXaTCY {
token: string
}
- type _sRFPXHX = hook.Event&RequestEvent&baseCollectionEventData
- interface FileDownloadRequestEvent extends _sRFPXHX {
+ type _sSSLPbT = hook.Event&RequestEvent&baseCollectionEventData
+ interface FileDownloadRequestEvent extends _sSSLPbT {
record?: Record
fileField?: FileField
servedPath: string
@@ -9768,80 +9801,80 @@ namespace core {
*/
thumbError: Error
}
- type _sZPkKFr = hook.Event&RequestEvent
- interface CollectionsListRequestEvent extends _sZPkKFr {
+ type _sBHjQYN = hook.Event&RequestEvent
+ interface CollectionsListRequestEvent extends _sBHjQYN {
collections: Array<(Collection | undefined)>
result?: search.Result
}
- type _sFIxzEG = hook.Event&RequestEvent
- interface CollectionsImportRequestEvent extends _sFIxzEG {
+ type _suRMEQi = hook.Event&RequestEvent
+ interface CollectionsImportRequestEvent extends _suRMEQi {
collectionsData: Array<_TygojaDict>
deleteMissing: boolean
}
- type _sKUvElw = hook.Event&RequestEvent&baseCollectionEventData
- interface CollectionRequestEvent extends _sKUvElw {
+ type _srHvMtM = hook.Event&RequestEvent&baseCollectionEventData
+ interface CollectionRequestEvent extends _srHvMtM {
}
- type _sZQgaiI = hook.Event&RequestEvent
- interface RealtimeConnectRequestEvent extends _sZQgaiI {
+ type _slFrNrp = hook.Event&RequestEvent
+ interface RealtimeConnectRequestEvent extends _slFrNrp {
client: subscriptions.Client
/**
* note: modifying it after the connect has no effect
*/
idleTimeout: time.Duration
}
- type _sSuIMSv = hook.Event&RequestEvent
- interface RealtimeMessageEvent extends _sSuIMSv {
+ type _sLJjGky = hook.Event&RequestEvent
+ interface RealtimeMessageEvent extends _sLJjGky {
client: subscriptions.Client
message?: subscriptions.Message
}
- type _shvJVSq = hook.Event&RequestEvent
- interface RealtimeSubscribeRequestEvent extends _shvJVSq {
+ type _suxTJjg = hook.Event&RequestEvent
+ interface RealtimeSubscribeRequestEvent extends _suxTJjg {
client: subscriptions.Client
subscriptions: Array
}
- type _sjLThjH = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordsListRequestEvent extends _sjLThjH {
+ type _sFhPrdO = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordsListRequestEvent extends _sFhPrdO {
/**
* @todo consider removing and maybe add as generic to the search.Result?
*/
records: Array<(Record | undefined)>
result?: search.Result
}
- type _sXtSbvi = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordRequestEvent extends _sXtSbvi {
+ type _saHanQJ = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordRequestEvent extends _saHanQJ {
record?: Record
}
- type _sojhWQK = hook.Event&baseRecordEventData
- interface RecordEnrichEvent extends _sojhWQK {
+ type _szajIdi = hook.Event&baseRecordEventData
+ interface RecordEnrichEvent extends _szajIdi {
app: App
requestInfo?: RequestInfo
}
- type _sPnFMal = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordCreateOTPRequestEvent extends _sPnFMal {
+ type _sBnNigu = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordCreateOTPRequestEvent extends _sBnNigu {
record?: Record
password: string
}
- type _sSOdGzw = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordAuthWithOTPRequestEvent extends _sSOdGzw {
+ type _sHURedw = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordAuthWithOTPRequestEvent extends _sHURedw {
record?: Record
otp?: OTP
}
- type _sAFesTl = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordAuthRequestEvent extends _sAFesTl {
+ type _sQWgoSv = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordAuthRequestEvent extends _sQWgoSv {
record?: Record
token: string
meta: any
authMethod: string
}
- type _sGNOizY = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordAuthWithPasswordRequestEvent extends _sGNOizY {
+ type _stdldOq = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordAuthWithPasswordRequestEvent extends _stdldOq {
record?: Record
identity: string
identityField: string
password: string
}
- type _sIuWdXu = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordAuthWithOAuth2RequestEvent extends _sIuWdXu {
+ type _swoBYye = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordAuthWithOAuth2RequestEvent extends _swoBYye {
providerName: string
providerClient: auth.Provider
record?: Record
@@ -9849,41 +9882,41 @@ namespace core {
createData: _TygojaDict
isNewRecord: boolean
}
- type _skoYlCa = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordAuthRefreshRequestEvent extends _skoYlCa {
+ type _szCfvnQ = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordAuthRefreshRequestEvent extends _szCfvnQ {
record?: Record
}
- type _sWpLPsE = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordRequestPasswordResetRequestEvent extends _sWpLPsE {
+ type _sLPbndB = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordRequestPasswordResetRequestEvent extends _sLPbndB {
record?: Record
}
- type _sJkJUZt = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordConfirmPasswordResetRequestEvent extends _sJkJUZt {
+ type _sVcqkmu = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordConfirmPasswordResetRequestEvent extends _sVcqkmu {
record?: Record
}
- type _spiojOR = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordRequestVerificationRequestEvent extends _spiojOR {
+ type _sMYvUAc = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordRequestVerificationRequestEvent extends _sMYvUAc {
record?: Record
}
- type _sMxoFyV = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordConfirmVerificationRequestEvent extends _sMxoFyV {
+ type _soRosYm = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordConfirmVerificationRequestEvent extends _soRosYm {
record?: Record
}
- type _sGCkdUA = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordRequestEmailChangeRequestEvent extends _sGCkdUA {
+ type _svBLQPR = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordRequestEmailChangeRequestEvent extends _svBLQPR {
record?: Record
newEmail: string
}
- type _soNtnzd = hook.Event&RequestEvent&baseCollectionEventData
- interface RecordConfirmEmailChangeRequestEvent extends _soNtnzd {
+ type _sagnnlS = hook.Event&RequestEvent&baseCollectionEventData
+ interface RecordConfirmEmailChangeRequestEvent extends _sagnnlS {
record?: Record
newEmail: string
}
/**
* ExternalAuth defines a Record proxy for working with the externalAuths collection.
*/
- type _sFhoiYT = Record
- interface ExternalAuth extends _sFhoiYT {
+ type _suGHpDy = Record
+ interface ExternalAuth extends _suGHpDy {
}
interface newExternalAuth {
/**
@@ -10150,6 +10183,12 @@ namespace core {
*/
intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void
}
+ interface defaultFieldHelpValidationRule {
+ /**
+ * DefaultFieldHelpValidationRule performs base validation on a field's "help" value.
+ */
+ (value: any): void
+ }
interface defaultFieldIdValidationRule {
/**
* DefaultFieldIdValidationRule performs base validation on a field id value.
@@ -10322,6 +10361,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Required will require the field value to be always "true".
*/
@@ -10434,6 +10478,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Min specifies the min allowed field value.
*
@@ -10558,6 +10607,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1).
*
@@ -10690,6 +10744,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* ExceptDomains will require the email domain to NOT be included in the listed ones.
*
@@ -10842,6 +10901,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* MaxSize specifies the maximum size of a single uploaded file (in bytes and up to 2^53-1).
*
@@ -11046,6 +11110,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Required will require the field coordinates to be non-zero (aka. not "Null Island").
*/
@@ -11158,6 +11227,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1).
*
@@ -11292,6 +11366,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Min specifies the min allowed field value.
*
@@ -11440,10 +11519,17 @@ namespace core {
*/
hidden: boolean
/**
+ * @todo remove
+ *
* Presentable hints the Dashboard UI to use the underlying
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Pattern specifies an optional regex pattern to match against the field value.
*
@@ -11637,6 +11723,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* CollectionId is the id of the related collection.
*/
@@ -11818,6 +11909,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Values specifies the list of accepted values.
*/
@@ -11968,6 +12064,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* Min specifies the minimum required string characters.
*
@@ -12130,6 +12231,11 @@ namespace core {
* field record value in the relation preview label.
*/
presentable: boolean
+ /**
+ * Help is an extra text explaining what the field is about.
+ * It is usually shown in Dashboard UI under the field input.
+ */
+ help: string
/**
* ExceptDomains will require the URL domain to NOT be included in the listed ones.
*
@@ -12345,8 +12451,8 @@ namespace core {
interface onlyFieldType {
type: string
}
- type _sLstiqt = Field
- interface fieldWithType extends _sLstiqt {
+ type _sGHfhOm = Field
+ interface fieldWithType extends _sGHfhOm {
type: string
}
interface fieldWithType {
@@ -12378,8 +12484,8 @@ namespace core {
*/
scan(value: any): void
}
- type _sZRVcVD = BaseModel
- interface Log extends _sZRVcVD {
+ type _sCwhdkm = BaseModel
+ interface Log extends _sCwhdkm {
created: types.DateTime
data: types.JSONMap
message: string
@@ -12425,8 +12531,8 @@ namespace core {
/**
* MFA defines a Record proxy for working with the mfas collection.
*/
- type _shxPFuR = Record
- interface MFA extends _shxPFuR {
+ type _seabzoM = Record
+ interface MFA extends _seabzoM {
}
interface newMFA {
/**
@@ -12648,8 +12754,8 @@ namespace core {
/**
* OTP defines a Record proxy for working with the otps collection.
*/
- type _sBeLRsQ = Record
- interface OTP extends _sBeLRsQ {
+ type _sApkWyq = Record
+ interface OTP extends _sApkWyq {
}
interface newOTP {
/**
@@ -12885,8 +12991,8 @@ namespace core {
}
interface runner {
}
- type _saOTAnI = BaseModel
- interface Record extends _saOTAnI {
+ type _sixuDWf = BaseModel
+ interface Record extends _sixuDWf {
}
interface newRecord {
/**
@@ -13361,8 +13467,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 _swwiIEU = Record
- interface BaseRecordProxy extends _swwiIEU {
+ type _sAAfrDL = Record
+ interface BaseRecordProxy extends _sAAfrDL {
}
interface BaseRecordProxy {
/**
@@ -13611,8 +13717,8 @@ namespace core {
/**
* Settings defines the PocketBase app settings.
*/
- type _sBWpWss = settings
- interface Settings extends _sBWpWss {
+ type _sGBqfIb = settings
+ interface Settings extends _sGBqfIb {
}
interface Settings {
/**
@@ -13796,6 +13902,12 @@ namespace core {
validate(): void
}
interface MetaConfig {
+ /**
+ * @todo experimental
+ *
+ * AccentColor specify the UI "accent" color (HEX).
+ */
+ accentColor: string
appName: string
appURL: string
senderName: string
@@ -13925,8 +14037,8 @@ namespace core {
*/
string(): string
}
- type _swJezTI = BaseModel
- interface Param extends _swJezTI {
+ type _swmWBcn = BaseModel
+ interface Param extends _swmWBcn {
created: types.DateTime
updated: types.DateTime
value: types.JSONRaw
@@ -13975,6 +14087,22 @@ namespace core {
*/
createViewFields(dangerousSelectQuery: string): FieldsList
}
+ interface DryRunViewResult {
+ fields: FieldsList
+ sample: Array<(Record | undefined)>
+ }
+ interface BaseApp {
+ /**
+ * DryRunView executes the provided query by creating a temporary view
+ * collection and returning a sample of the resulting query records (if valid).
+ *
+ * The same caveats from CreateViewFields apply here too.
+ *
+ * NB! Be aware that this method is vulnerable to SQL injection and the
+ * "dangerousSelectQuery" argument must come only from trusted input!
+ */
+ dryRunView(dangerousSelectQuery: string, sampleSize: number): (DryRunViewResult)
+ }
interface BaseApp {
/**
* FindRecordByViewFile returns the original Record of the provided view collection file.
@@ -14279,7 +14407,7 @@ namespace apis {
}
interface newRouter {
/**
- * NewRouter returns a new router instance loaded with the default app middlewares and api routes.
+ * NewRouter returns a new router instance loaded with the default app middlewares and routes.
*/
(app: CoreApp): (router.Router)
}
@@ -14356,6 +14484,14 @@ namespace apis {
interface BatchResponseError {
marshalJSON(): string|Array
}
+ interface providerListItem {
+ name: string
+ displayName: string
+ logo: string
+ }
+ interface dryRunViewForm {
+ query: string
+ }
interface collectionsImportForm {
collections: Array<_TygojaDict>
deleteMissing: boolean
@@ -14443,8 +14579,8 @@ namespace apis {
*/
(limitBytes: number): (hook.Handler)
}
- type _sFRBhMZ = io.ReadCloser
- interface limitedReader extends _sFRBhMZ {
+ type _sIyHjaB = io.ReadCloser
+ interface limitedReader extends _sIyHjaB {
}
interface limitedReader {
read(b: string|Array): number
@@ -14598,8 +14734,8 @@ namespace apis {
*/
(config: GzipConfig): (hook.Handler)
}
- type _seNzbcU = http.ResponseWriter&io.Writer
- interface gzipResponseWriter extends _seNzbcU {
+ type _sMXRnmN = http.ResponseWriter&io.Writer
+ interface gzipResponseWriter extends _sMXRnmN {
}
interface gzipResponseWriter {
writeHeader(code: number): void
@@ -14619,16 +14755,16 @@ namespace apis {
interface gzipResponseWriter {
unwrap(): http.ResponseWriter
}
- type _sLfCowm = sync.RWMutex
- interface rateLimiter extends _sLfCowm {
+ type _slRgPdG = sync.RWMutex
+ interface rateLimiter extends _slRgPdG {
}
/**
* @todo evaluate swiching to sliding window with approximation counter similar to Cloudflare.
*
* rateClient implements fixed window rate limit strategy.
*/
- type _seqmKwd = sync.Mutex
- interface rateClient extends _seqmKwd {
+ type _sZvOeZC = sync.Mutex
+ interface rateClient extends _sZvOeZC {
}
interface realtimeSubscribeForm {
clientId: string
@@ -14673,6 +14809,7 @@ namespace apis {
interface providerInfo {
name: string
displayName: string
+ logo: string
state: string
authURL: string
/**
@@ -14873,8 +15010,8 @@ namespace pocketbase {
* It implements [CoreApp] via embedding and all of the app interface methods
* could be accessed directly through the instance (eg. PocketBase.DataDir()).
*/
- type _sxZqaJI = CoreApp
- interface PocketBase extends _sxZqaJI {
+ type _syPxemM = CoreApp
+ interface PocketBase extends _syPxemM {
/**
* RootCmd is the main console command
*/
@@ -15188,91 +15325,6 @@ namespace io {
}
}
-/**
- * Package bytes implements functions for the manipulation of byte slices.
- * It is analogous to the facilities of the [strings] package.
- */
-namespace bytes {
- /**
- * A Reader implements the [io.Reader], [io.ReaderAt], [io.WriterTo], [io.Seeker],
- * [io.ByteScanner], and [io.RuneScanner] interfaces by reading from
- * a byte slice.
- * Unlike a [Buffer], a Reader is read-only and supports seeking.
- * The zero value for Reader operates like a Reader of an empty slice.
- */
- interface Reader {
- }
- interface Reader {
- /**
- * Len returns the number of bytes of the unread portion of the
- * slice.
- */
- len(): number
- }
- interface Reader {
- /**
- * Size returns the original length of the underlying byte slice.
- * Size is the number of bytes available for reading via [Reader.ReadAt].
- * The result is unaffected by any method calls except [Reader.Reset].
- */
- size(): number
- }
- interface Reader {
- /**
- * Read implements the [io.Reader] interface.
- */
- read(b: string|Array): number
- }
- interface Reader {
- /**
- * ReadAt implements the [io.ReaderAt] interface.
- */
- readAt(b: string|Array, off: number): number
- }
- interface Reader {
- /**
- * ReadByte implements the [io.ByteReader] interface.
- */
- readByte(): number
- }
- interface Reader {
- /**
- * UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface.
- */
- unreadByte(): void
- }
- interface Reader {
- /**
- * ReadRune implements the [io.RuneReader] interface.
- */
- readRune(): [number, number]
- }
- interface Reader {
- /**
- * UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface.
- */
- unreadRune(): void
- }
- interface Reader {
- /**
- * Seek implements the [io.Seeker] interface.
- */
- seek(offset: number, whence: number): number
- }
- interface Reader {
- /**
- * WriteTo implements the [io.WriterTo] interface.
- */
- writeTo(w: io.Writer): number
- }
- interface Reader {
- /**
- * Reset resets the [Reader] to be reading from b.
- */
- reset(b: string|Array): void
- }
-}
-
/**
* Package syscall contains an interface to the low-level operating system
* primitives. The details vary depending on the underlying system, and
@@ -16024,172 +16076,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].
- *
- * A Context may be canceled to indicate that work done on its behalf should stop.
- * A Context with a deadline is canceled after the deadline passes.
- * 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 directly 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. The go vet tool
- * checks that CancelFuncs are used on all control-flow paths.
- *
- * The [WithCancelCause], [WithDeadlineCause], and [WithTimeoutCause] functions
- * return 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. This is discussed further in
- * https://go.dev/blog/context-and-structs. 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://go.dev/blog/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:
- * DeadlineExceeded if the context's deadline passed,
- * or Canceled if the context was canceled for some other reason.
- * 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
@@ -16392,17 +16278,350 @@ namespace fs {
}
/**
- * 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 bytes implements functions for the manipulation of byte slices.
+ * It is analogous to the facilities of the [strings] package.
*/
-namespace bufio {
+namespace bytes {
/**
- * ReadWriter stores pointers to a [Reader] and a [Writer].
- * It implements [io.ReadWriter].
+ * A Reader implements the [io.Reader], [io.ReaderAt], [io.WriterTo], [io.Seeker],
+ * [io.ByteScanner], and [io.RuneScanner] interfaces by reading from
+ * a byte slice.
+ * Unlike a [Buffer], a Reader is read-only and supports seeking.
+ * The zero value for Reader operates like a Reader of an empty slice.
*/
- type _sUQolAm = Reader&Writer
- interface ReadWriter extends _sUQolAm {
+ interface Reader {
+ }
+ interface Reader {
+ /**
+ * Len returns the number of bytes of the unread portion of the
+ * slice.
+ */
+ len(): number
+ }
+ interface Reader {
+ /**
+ * Size returns the original length of the underlying byte slice.
+ * Size is the number of bytes available for reading via [Reader.ReadAt].
+ * The result is unaffected by any method calls except [Reader.Reset].
+ */
+ size(): number
+ }
+ interface Reader {
+ /**
+ * Read implements the [io.Reader] interface.
+ */
+ read(b: string|Array): number
+ }
+ interface Reader {
+ /**
+ * ReadAt implements the [io.ReaderAt] interface.
+ */
+ readAt(b: string|Array, off: number): number
+ }
+ interface Reader {
+ /**
+ * ReadByte implements the [io.ByteReader] interface.
+ */
+ readByte(): number
+ }
+ interface Reader {
+ /**
+ * UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface.
+ */
+ unreadByte(): void
+ }
+ interface Reader {
+ /**
+ * ReadRune implements the [io.RuneReader] interface.
+ */
+ readRune(): [number, number]
+ }
+ interface Reader {
+ /**
+ * UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface.
+ */
+ unreadRune(): void
+ }
+ interface Reader {
+ /**
+ * Seek implements the [io.Seeker] interface.
+ */
+ seek(offset: number, whence: number): number
+ }
+ interface Reader {
+ /**
+ * WriteTo implements the [io.WriterTo] interface.
+ */
+ writeTo(w: io.Writer): number
+ }
+ interface Reader {
+ /**
+ * Reset resets the [Reader] to be reading from b.
+ */
+ reset(b: string|Array): void
+ }
+}
+
+/**
+ * Package cron implements a crontab-like service to execute and schedule
+ * repeative tasks/jobs.
+ *
+ * Example:
+ *
+ * ```
+ * c := cron.New()
+ * c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
+ * c.Start()
+ * ```
+ */
+namespace cron {
+ /**
+ * Cron is a crontab-like struct for tasks/jobs scheduling.
+ */
+ interface Cron {
+ }
+ interface Cron {
+ /**
+ * SetInterval changes the current cron tick interval
+ * (it usually should be >= 1 minute).
+ */
+ setInterval(d: time.Duration): void
+ }
+ interface Cron {
+ /**
+ * SetTimezone changes the current cron tick timezone.
+ */
+ setTimezone(l: time.Location): void
+ }
+ interface Cron {
+ /**
+ * MustAdd is similar to Add() but panic on failure.
+ */
+ mustAdd(jobId: string, cronExpr: string, run: () => void): void
+ }
+ interface Cron {
+ /**
+ * Add registers a single cron job.
+ *
+ * If there is already a job with the provided id, then the old job
+ * will be replaced with the new one.
+ *
+ * cronExpr is a regular cron expression, eg. "0 *\/3 * * *" (aka. at minute 0 past every 3rd hour).
+ * Check cron.NewSchedule() for the supported tokens.
+ */
+ add(jobId: string, cronExpr: string, fn: () => void): void
+ }
+ interface Cron {
+ /**
+ * Remove removes a single cron job by its id.
+ */
+ remove(jobId: string): void
+ }
+ interface Cron {
+ /**
+ * RemoveAll removes all registered cron jobs.
+ */
+ removeAll(): void
+ }
+ interface Cron {
+ /**
+ * Total returns the current total number of registered cron jobs.
+ */
+ total(): number
+ }
+ interface Cron {
+ /**
+ * Jobs returns a shallow copy of the currently registered cron jobs.
+ */
+ jobs(): Array<(Job | undefined)>
+ }
+ interface Cron {
+ /**
+ * Stop stops the current cron ticker (if not already).
+ *
+ * You can resume the ticker by calling Start().
+ */
+ stop(): void
+ }
+ interface Cron {
+ /**
+ * Start starts the cron ticker.
+ *
+ * Calling Start() on already started cron will restart the ticker.
+ */
+ start(): void
+ }
+ interface Cron {
+ /**
+ * HasStarted checks whether the current Cron ticker has been started.
+ */
+ hasStarted(): boolean
+ }
+}
+
+/**
+ * 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].
+ *
+ * A Context may be canceled to indicate that work done on its behalf should stop.
+ * A Context with a deadline is canceled after the deadline passes.
+ * 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 directly 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. The go vet tool
+ * checks that CancelFuncs are used on all control-flow paths.
+ *
+ * The [WithCancelCause], [WithDeadlineCause], and [WithTimeoutCause] functions
+ * return 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. This is discussed further in
+ * https://go.dev/blog/context-and-structs. 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://go.dev/blog/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:
+ * DeadlineExceeded if the context's deadline passed,
+ * or Canceled if the context was canceled for some other reason.
+ * 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
}
}
@@ -16766,6 +16985,3333 @@ namespace syntax {
interface Flags extends Number{}
}
+/**
+ * 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]any 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 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 _srSsGWn = Reader&Writer
+ interface ReadWriter extends _srSsGWn {
+ }
+}
+
+/**
+ * Package multipart implements MIME multipart parsing, as defined in RFC
+ * 2046.
+ *
+ * The implementation is sufficient for HTTP (RFC 2388) and the multipart
+ * bodies generated by popular browsers.
+ *
+ * # Limits
+ *
+ * To protect against malicious inputs, this package sets limits on the size
+ * of the MIME data it processes.
+ *
+ * [Reader.NextPart] and [Reader.NextRawPart] limit the number of headers in a
+ * part to 10000 and [Reader.ReadForm] limits the total number of headers in all
+ * FileHeaders to 10000.
+ * These limits may be adjusted with the GODEBUG=multipartmaxheaders=
+ * setting.
+ *
+ * Reader.ReadForm further limits the number of parts in a form to 1000.
+ * This limit may be adjusted with the GODEBUG=multipartmaxparts=
+ * setting.
+ */
+namespace multipart {
+ /**
+ * A FileHeader describes a file part of a multipart request.
+ */
+ interface FileHeader {
+ filename: string
+ header: textproto.MIMEHeader
+ size: number
+ }
+ interface FileHeader {
+ /**
+ * Open opens and returns the [FileHeader]'s associated File.
+ */
+ open(): File
+ }
+}
+
+/**
+ * Package http provides HTTP client and server implementations.
+ *
+ * [Get], [Head], [Post], and [PostForm] make HTTP (or HTTPS) requests:
+ *
+ * ```
+ * resp, err := http.Get("http://example.com/")
+ * ...
+ * resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
+ * ...
+ * resp, err := http.PostForm("http://example.com/form",
+ * url.Values{"key": {"Value"}, "id": {"123"}})
+ * ```
+ *
+ * The caller must close the response body when finished with it:
+ *
+ * ```
+ * resp, err := http.Get("http://example.com/")
+ * if err != nil {
+ * // handle error
+ * }
+ * defer resp.Body.Close()
+ * body, err := io.ReadAll(resp.Body)
+ * // ...
+ * ```
+ *
+ * # Clients and Transports
+ *
+ * For control over HTTP client headers, redirect policy, and other
+ * settings, create a [Client]:
+ *
+ * ```
+ * client := &http.Client{
+ * CheckRedirect: redirectPolicyFunc,
+ * }
+ *
+ * resp, err := client.Get("http://example.com")
+ * // ...
+ *
+ * req, err := http.NewRequest("GET", "http://example.com", nil)
+ * // ...
+ * req.Header.Add("If-None-Match", `W/"wyzzy"`)
+ * resp, err := client.Do(req)
+ * // ...
+ * ```
+ *
+ * For control over proxies, TLS configuration, keep-alives,
+ * compression, and other settings, create a [Transport]:
+ *
+ * ```
+ * tr := &http.Transport{
+ * MaxIdleConns: 10,
+ * IdleConnTimeout: 30 * time.Second,
+ * DisableCompression: true,
+ * }
+ * client := &http.Client{Transport: tr}
+ * resp, err := client.Get("https://example.com")
+ * ```
+ *
+ * Clients and Transports are safe for concurrent use by multiple
+ * goroutines and for efficiency should only be created once and re-used.
+ *
+ * # Servers
+ *
+ * ListenAndServe starts an HTTP server with a given address and handler.
+ * The handler is usually nil, which means to use [DefaultServeMux].
+ * [Handle] and [HandleFunc] add handlers to [DefaultServeMux]:
+ *
+ * ```
+ * http.Handle("/foo", fooHandler)
+ *
+ * http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
+ * fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
+ * })
+ *
+ * log.Fatal(http.ListenAndServe(":8080", nil))
+ * ```
+ *
+ * More control over the server's behavior is available by creating a
+ * custom Server:
+ *
+ * ```
+ * s := &http.Server{
+ * Addr: ":8080",
+ * Handler: myHandler,
+ * ReadTimeout: 10 * time.Second,
+ * WriteTimeout: 10 * time.Second,
+ * MaxHeaderBytes: 1 << 20,
+ * }
+ * log.Fatal(s.ListenAndServe())
+ * ```
+ *
+ * # HTTP/2
+ *
+ * Starting with Go 1.6, the http package has transparent support for the
+ * HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2
+ * can do so by setting [Transport.TLSNextProto] (for clients) or
+ * [Server.TLSNextProto] (for servers) to a non-nil, empty
+ * map. Alternatively, the following GODEBUG settings are
+ * currently supported:
+ *
+ * ```
+ * GODEBUG=http2client=0 # disable HTTP/2 client support
+ * GODEBUG=http2server=0 # disable HTTP/2 server support
+ * GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs
+ * GODEBUG=http2debug=2 # ... even more verbose, with frame dumps
+ * ```
+ *
+ * Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug
+ *
+ * The http package's [Transport] and [Server] both automatically enable
+ * HTTP/2 support for simple configurations. To enable HTTP/2 for more
+ * complex configurations, to use lower-level HTTP/2 features, or to use
+ * a newer version of Go's http2 package, import "golang.org/x/net/http2"
+ * directly and use its ConfigureTransport and/or ConfigureServer
+ * functions. Manually configuring HTTP/2 via the golang.org/x/net/http2
+ * package takes precedence over the net/http package's built-in HTTP/2
+ * support.
+ */
+namespace http {
+ // @ts-ignore
+ import mathrand = rand
+ /**
+ * PushOptions describes options for [Pusher.Push].
+ */
+ interface PushOptions {
+ /**
+ * Method specifies the HTTP method for the promised request.
+ * If set, it must be "GET" or "HEAD". Empty means "GET".
+ */
+ method: string
+ /**
+ * Header specifies additional promised request headers. This cannot
+ * include HTTP/2 pseudo header fields like ":path" and ":scheme",
+ * which will be added automatically.
+ */
+ header: Header
+ }
+ // @ts-ignore
+ import urlpkg = url
+ /**
+ * A Request represents an HTTP request received by a server
+ * or to be sent by a client.
+ *
+ * The field semantics differ slightly between client and server
+ * usage. In addition to the notes on the fields below, see the
+ * documentation for [Request.Write] and [RoundTripper].
+ */
+ interface Request {
+ /**
+ * Method specifies the HTTP method (GET, POST, PUT, etc.).
+ * For client requests, an empty string means GET.
+ */
+ method: string
+ /**
+ * URL specifies either the URI being requested (for server
+ * requests) or the URL to access (for client requests).
+ *
+ * For server requests, the URL is parsed from the URI
+ * supplied on the Request-Line as stored in RequestURI. For
+ * most requests, fields other than Path and RawQuery will be
+ * empty. (See RFC 7230, Section 5.3)
+ *
+ * For client requests, the URL's Host specifies the server to
+ * connect to, while the Request's Host field optionally
+ * specifies the Host header value to send in the HTTP
+ * request.
+ */
+ url?: url.URL
+ /**
+ * The protocol version for incoming server requests.
+ *
+ * For client requests, these fields are ignored. The HTTP
+ * client code always uses either HTTP/1.1 or HTTP/2.
+ * See the docs on Transport for details.
+ */
+ proto: string // "HTTP/1.0"
+ protoMajor: number // 1
+ protoMinor: number // 0
+ /**
+ * Header contains the request header fields either received
+ * by the server or to be sent by the client.
+ *
+ * If a server received a request with header lines,
+ *
+ * ```
+ * Host: example.com
+ * accept-encoding: gzip, deflate
+ * Accept-Language: en-us
+ * fOO: Bar
+ * foo: two
+ * ```
+ *
+ * then
+ *
+ * ```
+ * Header = map[string][]string{
+ * "Accept-Encoding": {"gzip, deflate"},
+ * "Accept-Language": {"en-us"},
+ * "Foo": {"Bar", "two"},
+ * }
+ * ```
+ *
+ * For incoming requests, the Host header is promoted to the
+ * Request.Host field and removed from the Header map.
+ *
+ * HTTP defines that header names are case-insensitive. The
+ * request parser implements this by using CanonicalHeaderKey,
+ * making the first character and any characters following a
+ * hyphen uppercase and the rest lowercase.
+ *
+ * For client requests, certain headers such as Content-Length
+ * and Connection are automatically written when needed and
+ * values in Header may be ignored. See the documentation
+ * for the Request.Write method.
+ */
+ header: Header
+ /**
+ * Body is the request's body.
+ *
+ * For client requests, a nil body means the request has no
+ * body, such as a GET request. The HTTP Client's Transport
+ * is responsible for calling the Close method.
+ *
+ * For server requests, the Request Body is always non-nil
+ * but will return EOF immediately when no body is present.
+ * The Server will close the request body. The ServeHTTP
+ * Handler does not need to.
+ *
+ * Body must allow Read to be called concurrently with Close.
+ * In particular, calling Close should unblock a Read waiting
+ * for input.
+ */
+ body: io.ReadCloser
+ /**
+ * GetBody defines an optional func to return a new copy of
+ * Body. It is used for client requests when a redirect requires
+ * reading the body more than once. Use of GetBody still
+ * requires setting Body.
+ *
+ * For server requests, it is unused.
+ */
+ getBody: () => io.ReadCloser
+ /**
+ * ContentLength records the length of the associated content.
+ * The value -1 indicates that the length is unknown.
+ * Values >= 0 indicate that the given number of bytes may
+ * be read from Body.
+ *
+ * For client requests, a value of 0 with a non-nil Body is
+ * also treated as unknown.
+ */
+ contentLength: number
+ /**
+ * TransferEncoding lists the transfer encodings from outermost to
+ * innermost. An empty list denotes the "identity" encoding.
+ * TransferEncoding can usually be ignored; chunked encoding is
+ * automatically added and removed as necessary when sending and
+ * receiving requests.
+ */
+ transferEncoding: Array
+ /**
+ * Close indicates whether to close the connection after
+ * replying to this request (for servers) or after sending this
+ * request and reading its response (for clients).
+ *
+ * For server requests, the HTTP server handles this automatically
+ * and this field is not needed by Handlers.
+ *
+ * For client requests, setting this field prevents re-use of
+ * TCP connections between requests to the same hosts, as if
+ * Transport.DisableKeepAlives were set.
+ */
+ close: boolean
+ /**
+ * For server requests, Host specifies the host on which the
+ * URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this
+ * is either the value of the "Host" header or the host name
+ * given in the URL itself. For HTTP/2, it is the value of the
+ * ":authority" pseudo-header field.
+ * It may be of the form "host:port". For international domain
+ * names, Host may be in Punycode or Unicode form. Use
+ * golang.org/x/net/idna to convert it to either format if
+ * needed.
+ * To prevent DNS rebinding attacks, server Handlers should
+ * validate that the Host header has a value for which the
+ * Handler considers itself authoritative. The included
+ * ServeMux supports patterns registered to particular host
+ * names and thus protects its registered Handlers.
+ *
+ * For client requests, Host optionally overrides the Host
+ * header to send. If empty, the Request.Write method uses
+ * the value of URL.Host. Host may contain an international
+ * domain name.
+ */
+ host: string
+ /**
+ * Form contains the parsed form data, including both the URL
+ * field's query parameters and the PATCH, POST, or PUT form data.
+ * This field is only available after ParseForm is called.
+ * The HTTP client ignores Form and uses Body instead.
+ */
+ form: url.Values
+ /**
+ * PostForm contains the parsed form data from PATCH, POST
+ * or PUT body parameters.
+ *
+ * This field is only available after ParseForm is called.
+ * The HTTP client ignores PostForm and uses Body instead.
+ */
+ postForm: url.Values
+ /**
+ * MultipartForm is the parsed multipart form, including file uploads.
+ * This field is only available after ParseMultipartForm is called.
+ * The HTTP client ignores MultipartForm and uses Body instead.
+ */
+ multipartForm?: multipart.Form
+ /**
+ * Trailer specifies additional headers that are sent after the request
+ * body.
+ *
+ * For server requests, the Trailer map initially contains only the
+ * trailer keys, with nil values. (The client declares which trailers it
+ * will later send.) While the handler is reading from Body, it must
+ * not reference Trailer. After reading from Body returns EOF, Trailer
+ * can be read again and will contain non-nil values, if they were sent
+ * by the client.
+ *
+ * For client requests, Trailer must be initialized to a map containing
+ * the trailer keys to later send. The values may be nil or their final
+ * values. The ContentLength must be 0 or -1, to send a chunked request.
+ * After the HTTP request is sent the map values can be updated while
+ * the request body is read. Once the body returns EOF, the caller must
+ * not mutate Trailer.
+ *
+ * Few HTTP clients, servers, or proxies support HTTP trailers.
+ */
+ trailer: Header
+ /**
+ * RemoteAddr allows HTTP servers and other software to record
+ * the network address that sent the request, usually for
+ * logging. This field is not filled in by ReadRequest and
+ * has no defined format. The HTTP server in this package
+ * sets RemoteAddr to an "IP:port" address before invoking a
+ * handler.
+ * This field is ignored by the HTTP client.
+ */
+ remoteAddr: string
+ /**
+ * RequestURI is the unmodified request-target of the
+ * Request-Line (RFC 7230, Section 3.1.1) as sent by the client
+ * to a server. Usually the URL field should be used instead.
+ * It is an error to set this field in an HTTP client request.
+ */
+ requestURI: string
+ /**
+ * TLS allows HTTP servers and other software to record
+ * information about the TLS connection on which the request
+ * was received. This field is not filled in by ReadRequest.
+ * The HTTP server in this package sets the field for
+ * TLS-enabled connections before invoking a handler;
+ * otherwise it leaves the field nil.
+ * This field is ignored by the HTTP client.
+ */
+ tls?: any
+ /**
+ * Cancel is an optional channel whose closure indicates that the client
+ * request should be regarded as canceled. Not all implementations of
+ * RoundTripper may support Cancel.
+ *
+ * For server requests, this field is not applicable.
+ *
+ * Deprecated: Set the Request's context with NewRequestWithContext
+ * instead. If a Request's Cancel field and context are both
+ * set, it is undefined whether Cancel is respected.
+ */
+ cancel: undefined
+ /**
+ * Response is the redirect response which caused this request
+ * to be created. This field is only populated during client
+ * redirects.
+ */
+ response?: Response
+ /**
+ * Pattern is the [ServeMux] pattern that matched the request.
+ * It is empty if the request was not matched against a pattern.
+ */
+ pattern: string
+ }
+ interface Request {
+ /**
+ * Context returns the request's context. To change the context, use
+ * [Request.Clone] or [Request.WithContext].
+ *
+ * The returned context is always non-nil; it defaults to the
+ * background context.
+ *
+ * For outgoing client requests, the context controls cancellation.
+ *
+ * For incoming server requests, the context is canceled when the
+ * client's connection closes, the request is canceled (with HTTP/2),
+ * or when the ServeHTTP method returns.
+ */
+ context(): context.Context
+ }
+ interface Request {
+ /**
+ * WithContext returns a shallow copy of r with its context changed
+ * to ctx. The provided ctx must be non-nil.
+ *
+ * For outgoing client request, the context controls the entire
+ * lifetime of a request and its response: obtaining a connection,
+ * sending the request, and reading the response headers and body.
+ *
+ * To create a new request with a context, use [NewRequestWithContext].
+ * To make a deep copy of a request with a new context, use [Request.Clone].
+ */
+ withContext(ctx: context.Context): (Request)
+ }
+ interface Request {
+ /**
+ * Clone returns a deep copy of r with its context changed to ctx.
+ * The provided ctx must be non-nil.
+ *
+ * Clone only makes a shallow copy of the Body field.
+ *
+ * For an outgoing client request, the context controls the entire
+ * lifetime of a request and its response: obtaining a connection,
+ * sending the request, and reading the response headers and body.
+ */
+ clone(ctx: context.Context): (Request)
+ }
+ interface Request {
+ /**
+ * ProtoAtLeast reports whether the HTTP protocol used
+ * in the request is at least major.minor.
+ */
+ protoAtLeast(major: number, minor: number): boolean
+ }
+ interface Request {
+ /**
+ * UserAgent returns the client's User-Agent, if sent in the request.
+ */
+ userAgent(): string
+ }
+ interface Request {
+ /**
+ * Cookies parses and returns the HTTP cookies sent with the request.
+ */
+ cookies(): Array<(Cookie | undefined)>
+ }
+ interface Request {
+ /**
+ * CookiesNamed parses and returns the named HTTP cookies sent with the request
+ * or an empty slice if none matched.
+ */
+ cookiesNamed(name: string): Array<(Cookie | undefined)>
+ }
+ interface Request {
+ /**
+ * Cookie returns the named cookie provided in the request or
+ * [ErrNoCookie] if not found.
+ * If multiple cookies match the given name, only one cookie will
+ * be returned.
+ */
+ cookie(name: string): (Cookie)
+ }
+ interface Request {
+ /**
+ * AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
+ * AddCookie does not attach more than one [Cookie] header field. That
+ * means all cookies, if any, are written into the same line,
+ * separated by semicolon.
+ * AddCookie only sanitizes c's name and value, and does not sanitize
+ * a Cookie header already present in the request.
+ */
+ addCookie(c: Cookie): void
+ }
+ interface Request {
+ /**
+ * Referer returns the referring URL, if sent in the request.
+ *
+ * Referer is misspelled as in the request itself, a mistake from the
+ * earliest days of HTTP. This value can also be fetched from the
+ * [Header] map as Header["Referer"]; the benefit of making it available
+ * as a method is that the compiler can diagnose programs that use the
+ * alternate (correct English) spelling req.Referrer() but cannot
+ * diagnose programs that use Header["Referrer"].
+ */
+ referer(): string
+ }
+ interface Request {
+ /**
+ * MultipartReader returns a MIME multipart reader if this is a
+ * multipart/form-data or a multipart/mixed POST request, else returns nil and an error.
+ * Use this function instead of [Request.ParseMultipartForm] to
+ * process the request body as a stream.
+ */
+ multipartReader(): (multipart.Reader)
+ }
+ interface Request {
+ /**
+ * Write writes an HTTP/1.1 request, which is the header and body, in wire format.
+ * This method consults the following fields of the request:
+ *
+ * ```
+ * Host
+ * URL
+ * Method (defaults to "GET")
+ * Header
+ * ContentLength
+ * TransferEncoding
+ * Body
+ * ```
+ *
+ * If Body is present, Content-Length is <= 0 and [Request.TransferEncoding]
+ * hasn't been set to "identity", Write adds "Transfer-Encoding:
+ * chunked" to the header. Body is closed after it is sent.
+ */
+ write(w: io.Writer): void
+ }
+ interface Request {
+ /**
+ * WriteProxy is like [Request.Write] but writes the request in the form
+ * expected by an HTTP proxy. In particular, [Request.WriteProxy] writes the
+ * initial Request-URI line of the request with an absolute URI, per
+ * section 5.3 of RFC 7230, including the scheme and host.
+ * In either case, WriteProxy also writes a Host header, using
+ * either r.Host or r.URL.Host.
+ */
+ writeProxy(w: io.Writer): void
+ }
+ interface Request {
+ /**
+ * BasicAuth returns the username and password provided in the request's
+ * Authorization header, if the request uses HTTP Basic Authentication.
+ * See RFC 2617, Section 2.
+ */
+ basicAuth(): [string, string, boolean]
+ }
+ interface Request {
+ /**
+ * SetBasicAuth sets the request's Authorization header to use HTTP
+ * Basic Authentication with the provided username and password.
+ *
+ * With HTTP Basic Authentication the provided username and password
+ * are not encrypted. It should generally only be used in an HTTPS
+ * request.
+ *
+ * The username may not contain a colon. Some protocols may impose
+ * additional requirements on pre-escaping the username and
+ * password. For instance, when used with OAuth2, both arguments must
+ * be URL encoded first with [url.QueryEscape].
+ */
+ setBasicAuth(username: string, password: string): void
+ }
+ interface Request {
+ /**
+ * ParseForm populates r.Form and r.PostForm.
+ *
+ * For all requests, ParseForm parses the raw query from the URL and updates
+ * r.Form.
+ *
+ * For POST, PUT, and PATCH requests, it also reads the request body, parses it
+ * as a form and puts the results into both r.PostForm and r.Form. Request body
+ * parameters take precedence over URL query string values in r.Form.
+ *
+ * If the request Body's size has not already been limited by [MaxBytesReader],
+ * the size is capped at 10MB.
+ *
+ * For other HTTP methods, or when the Content-Type is not
+ * application/x-www-form-urlencoded, the request Body is not read, and
+ * r.PostForm is initialized to a non-nil, empty value.
+ *
+ * [Request.ParseMultipartForm] calls ParseForm automatically.
+ * ParseForm is idempotent.
+ */
+ parseForm(): void
+ }
+ interface Request {
+ /**
+ * ParseMultipartForm parses a request body as multipart/form-data.
+ * The whole request body is parsed and up to a total of maxMemory bytes of
+ * its file parts are stored in memory, with the remainder stored on
+ * disk in temporary files.
+ * ParseMultipartForm calls [Request.ParseForm] if necessary.
+ * If ParseForm returns an error, ParseMultipartForm returns it but also
+ * continues parsing the request body.
+ * After one call to ParseMultipartForm, subsequent calls have no effect.
+ */
+ parseMultipartForm(maxMemory: number): void
+ }
+ interface Request {
+ /**
+ * FormValue returns the first value for the named component of the query.
+ * The precedence order:
+ * 1. application/x-www-form-urlencoded form body (POST, PUT, PATCH only)
+ * 2. query parameters (always)
+ * 3. multipart/form-data form body (always)
+ *
+ * FormValue calls [Request.ParseMultipartForm] and [Request.ParseForm]
+ * if necessary and ignores any errors returned by these functions.
+ * If key is not present, FormValue returns the empty string.
+ * To access multiple values of the same key, call ParseForm and
+ * then inspect [Request.Form] directly.
+ */
+ formValue(key: string): string
+ }
+ interface Request {
+ /**
+ * PostFormValue returns the first value for the named component of the POST,
+ * PUT, or PATCH request body. URL query parameters are ignored.
+ * PostFormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary and ignores
+ * any errors returned by these functions.
+ * If key is not present, PostFormValue returns the empty string.
+ */
+ postFormValue(key: string): string
+ }
+ interface Request {
+ /**
+ * FormFile returns the first file for the provided form key.
+ * FormFile calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary.
+ */
+ formFile(key: string): [multipart.File, (multipart.FileHeader)]
+ }
+ interface Request {
+ /**
+ * PathValue returns the value for the named path wildcard in the [ServeMux] pattern
+ * that matched the request.
+ * It returns the empty string if the request was not matched against a pattern
+ * or there is no such wildcard in the pattern.
+ */
+ pathValue(name: string): string
+ }
+ interface Request {
+ /**
+ * SetPathValue sets name to value, so that subsequent calls to r.PathValue(name)
+ * return value.
+ */
+ setPathValue(name: string, value: string): void
+ }
+ /**
+ * A Handler responds to an HTTP request.
+ *
+ * [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter]
+ * and then return. Returning signals that the request is finished; it
+ * is not valid to use the [ResponseWriter] or read from the
+ * [Request.Body] after or concurrently with the completion of the
+ * ServeHTTP call.
+ *
+ * Depending on the HTTP client software, HTTP protocol version, and
+ * any intermediaries between the client and the Go server, it may not
+ * be possible to read from the [Request.Body] after writing to the
+ * [ResponseWriter]. Cautious handlers should read the [Request.Body]
+ * first, and then reply.
+ *
+ * Except for reading the body, handlers should not modify the
+ * provided Request.
+ *
+ * If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
+ * that the effect of the panic was isolated to the active request.
+ * It recovers the panic, logs a stack trace to the server error log,
+ * and either closes the network connection or sends an HTTP/2
+ * RST_STREAM, depending on the HTTP protocol. To abort a handler so
+ * the client sees an interrupted response but the server doesn't log
+ * an error, panic with the value [ErrAbortHandler].
+ */
+ interface Handler {
+ [key:string]: any;
+ serveHTTP(_arg0: ResponseWriter, _arg1: Request): void
+ }
+ /**
+ * A ResponseWriter interface is used by an HTTP handler to
+ * construct an HTTP response.
+ *
+ * A ResponseWriter may not be used after [Handler.ServeHTTP] has returned.
+ */
+ interface ResponseWriter {
+ [key:string]: any;
+ /**
+ * Header returns the header map that will be sent by
+ * [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which
+ * [Handler] implementations can set HTTP trailers.
+ *
+ * Changing the header map after a call to [ResponseWriter.WriteHeader] (or
+ * [ResponseWriter.Write]) has no effect unless the HTTP status code was of the
+ * 1xx class or the modified headers are trailers.
+ *
+ * There are two ways to set Trailers. The preferred way is to
+ * predeclare in the headers which trailers you will later
+ * send by setting the "Trailer" header to the names of the
+ * trailer keys which will come later. In this case, those
+ * keys of the Header map are treated as if they were
+ * trailers. See the example. The second way, for trailer
+ * keys not known to the [Handler] until after the first [ResponseWriter.Write],
+ * is to prefix the [Header] map keys with the [TrailerPrefix]
+ * constant value.
+ *
+ * To suppress automatic response headers (such as "Date"), set
+ * their value to nil.
+ */
+ header(): Header
+ /**
+ * Write writes the data to the connection as part of an HTTP reply.
+ *
+ * If [ResponseWriter.WriteHeader] has not yet been called, Write calls
+ * WriteHeader(http.StatusOK) before writing the data. If the Header
+ * does not contain a Content-Type line, Write adds a Content-Type set
+ * to the result of passing the initial 512 bytes of written data to
+ * [DetectContentType]. Additionally, if the total size of all written
+ * data is under a few KB and there are no Flush calls, the
+ * Content-Length header is added automatically.
+ *
+ * Depending on the HTTP protocol version and the client, calling
+ * Write or WriteHeader may prevent future reads on the
+ * Request.Body. For HTTP/1.x requests, handlers should read any
+ * needed request body data before writing the response. Once the
+ * headers have been flushed (due to either an explicit Flusher.Flush
+ * call or writing enough data to trigger a flush), the request body
+ * may be unavailable. For HTTP/2 requests, the Go HTTP server permits
+ * handlers to continue to read the request body while concurrently
+ * writing the response. However, such behavior may not be supported
+ * by all HTTP/2 clients. Handlers should read before writing if
+ * possible to maximize compatibility.
+ */
+ write(_arg0: string|Array): number
+ /**
+ * WriteHeader sends an HTTP response header with the provided
+ * status code.
+ *
+ * If WriteHeader is not called explicitly, the first call to Write
+ * will trigger an implicit WriteHeader(http.StatusOK).
+ * Thus explicit calls to WriteHeader are mainly used to
+ * send error codes or 1xx informational responses.
+ *
+ * The provided code must be a valid HTTP 1xx-5xx status code.
+ * Any number of 1xx headers may be written, followed by at most
+ * one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx
+ * headers may be buffered. Use the Flusher interface to send
+ * buffered data. The header map is cleared when 2xx-5xx headers are
+ * sent, but not with 1xx headers.
+ *
+ * The server will automatically send a 100 (Continue) header
+ * on the first read from the request body if the request has
+ * an "Expect: 100-continue" header.
+ */
+ writeHeader(statusCode: number): void
+ }
+ /**
+ * A Server defines parameters for running an HTTP server.
+ * The zero value for Server is a valid configuration.
+ */
+ interface Server {
+ /**
+ * Addr optionally specifies the TCP address for the server to listen on,
+ * in the form "host:port". If empty, ":http" (port 80) is used.
+ * The service names are defined in RFC 6335 and assigned by IANA.
+ * See net.Dial for details of the address format.
+ */
+ addr: string
+ handler: Handler // handler to invoke, http.DefaultServeMux if nil
+ /**
+ * DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
+ * otherwise responds with 200 OK and Content-Length: 0.
+ */
+ disableGeneralOptionsHandler: boolean
+ /**
+ * TLSConfig optionally provides a TLS configuration for use
+ * by ServeTLS and ListenAndServeTLS. Note that this value is
+ * cloned by ServeTLS and ListenAndServeTLS, so it's not
+ * possible to modify the configuration with methods like
+ * tls.Config.SetSessionTicketKeys. To use
+ * SetSessionTicketKeys, use Server.Serve with a TLS Listener
+ * instead.
+ */
+ tlsConfig?: any
+ /**
+ * ReadTimeout is the maximum duration for reading the entire
+ * request, including the body. A zero or negative value means
+ * there will be no timeout.
+ *
+ * Because ReadTimeout does not let Handlers make per-request
+ * decisions on each request body's acceptable deadline or
+ * upload rate, most users will prefer to use
+ * ReadHeaderTimeout. It is valid to use them both.
+ */
+ readTimeout: time.Duration
+ /**
+ * ReadHeaderTimeout is the amount of time allowed to read
+ * request headers. The connection's read deadline is reset
+ * after reading the headers and the Handler can decide what
+ * is considered too slow for the body. If zero, the value of
+ * ReadTimeout is used. If negative, or if zero and ReadTimeout
+ * is zero or negative, there is no timeout.
+ */
+ readHeaderTimeout: time.Duration
+ /**
+ * WriteTimeout is the maximum duration before timing out
+ * writes of the response. It is reset whenever a new
+ * request's header is read. Like ReadTimeout, it does not
+ * let Handlers make decisions on a per-request basis.
+ * A zero or negative value means there will be no timeout.
+ */
+ writeTimeout: time.Duration
+ /**
+ * IdleTimeout is the maximum amount of time to wait for the
+ * next request when keep-alives are enabled. If zero, the value
+ * of ReadTimeout is used. If negative, or if zero and ReadTimeout
+ * is zero or negative, there is no timeout.
+ */
+ idleTimeout: time.Duration
+ /**
+ * MaxHeaderBytes controls the maximum number of bytes the
+ * server will read parsing the request header's keys and
+ * values, including the request line. It does not limit the
+ * size of the request body.
+ * If zero, DefaultMaxHeaderBytes is used.
+ */
+ maxHeaderBytes: number
+ /**
+ * TLSNextProto optionally specifies a function to take over
+ * ownership of the provided TLS connection when an ALPN
+ * protocol upgrade has occurred. The map key is the protocol
+ * name negotiated. The Handler argument should be used to
+ * handle HTTP requests and will initialize the Request's TLS
+ * and RemoteAddr if not already set. The connection is
+ * automatically closed when the function returns.
+ * If TLSNextProto is not nil, HTTP/2 support is not enabled
+ * automatically.
+ */
+ tlsNextProto: _TygojaDict
+ /**
+ * ConnState specifies an optional callback function that is
+ * called when a client connection changes state. See the
+ * ConnState type and associated constants for details.
+ */
+ connState: (_arg0: net.Conn, _arg1: ConnState) => void
+ /**
+ * ErrorLog specifies an optional logger for errors accepting
+ * connections, unexpected behavior from handlers, and
+ * underlying FileSystem errors.
+ * If nil, logging is done via the log package's standard logger.
+ */
+ errorLog?: any
+ /**
+ * BaseContext optionally specifies a function that returns
+ * the base context for incoming requests on this server.
+ * The provided Listener is the specific Listener that's
+ * about to start accepting requests.
+ * If BaseContext is nil, the default is context.Background().
+ * If non-nil, it must return a non-nil context.
+ */
+ baseContext: (_arg0: net.Listener) => context.Context
+ /**
+ * ConnContext optionally specifies a function that modifies
+ * the context used for a new connection c. The provided ctx
+ * is derived from the base context and has a ServerContextKey
+ * value.
+ */
+ connContext: (ctx: context.Context, c: net.Conn) => context.Context
+ /**
+ * HTTP2 configures HTTP/2 connections.
+ *
+ * This field does not yet have any effect.
+ * See https://go.dev/issue/67813.
+ */
+ http2?: HTTP2Config
+ /**
+ * Protocols is the set of protocols accepted by the server.
+ *
+ * If Protocols includes UnencryptedHTTP2, the server will accept
+ * unencrypted HTTP/2 connections. The server can serve both
+ * HTTP/1 and unencrypted HTTP/2 on the same address and port.
+ *
+ * If Protocols is nil, the default is usually HTTP/1 and HTTP/2.
+ * If TLSNextProto is non-nil and does not contain an "h2" entry,
+ * the default is HTTP/1 only.
+ */
+ protocols?: Protocols
+ }
+ interface Server {
+ /**
+ * Close immediately closes all active net.Listeners and any
+ * connections in state [StateNew], [StateActive], or [StateIdle]. For a
+ * graceful shutdown, use [Server.Shutdown].
+ *
+ * Close does not attempt to close (and does not even know about)
+ * any hijacked connections, such as WebSockets.
+ *
+ * Close returns any error returned from closing the [Server]'s
+ * underlying Listener(s).
+ */
+ close(): void
+ }
+ interface Server {
+ /**
+ * Shutdown gracefully shuts down the server without interrupting any
+ * active connections. Shutdown works by first closing all open
+ * listeners, then closing all idle connections, and then waiting
+ * indefinitely for connections to return to idle and then shut down.
+ * If the provided context expires before the shutdown is complete,
+ * Shutdown returns the context's error, otherwise it returns any
+ * error returned from closing the [Server]'s underlying Listener(s).
+ *
+ * When Shutdown is called, [Serve], [ServeTLS], [ListenAndServe], and
+ * [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the
+ * program doesn't exit and waits instead for Shutdown to return.
+ *
+ * Shutdown does not attempt to close nor wait for hijacked
+ * connections such as WebSockets. The caller of Shutdown should
+ * separately notify such long-lived connections of shutdown and wait
+ * for them to close, if desired. See [Server.RegisterOnShutdown] for a way to
+ * register shutdown notification functions.
+ *
+ * Once Shutdown has been called on a server, it may not be reused;
+ * future calls to methods such as Serve will return ErrServerClosed.
+ */
+ shutdown(ctx: context.Context): void
+ }
+ interface Server {
+ /**
+ * RegisterOnShutdown registers a function to call on [Server.Shutdown].
+ * This can be used to gracefully shutdown connections that have
+ * undergone ALPN protocol upgrade or that have been hijacked.
+ * This function should start protocol-specific graceful shutdown,
+ * but should not wait for shutdown to complete.
+ */
+ registerOnShutdown(f: () => void): void
+ }
+ interface Server {
+ /**
+ * ListenAndServe listens on the TCP network address s.Addr and then
+ * calls [Serve] to handle requests on incoming connections.
+ * Accepted connections are configured to enable TCP keep-alives.
+ *
+ * If s.Addr is blank, ":http" is used.
+ *
+ * ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close],
+ * the returned error is [ErrServerClosed].
+ */
+ listenAndServe(): void
+ }
+ interface Server {
+ /**
+ * Serve accepts incoming connections on the Listener l, creating a
+ * new service goroutine for each. The service goroutines read requests and
+ * then call s.Handler to reply to them.
+ *
+ * HTTP/2 support is only enabled if the Listener returns [*tls.Conn]
+ * connections and they were configured with "h2" in the TLS
+ * Config.NextProtos.
+ *
+ * Serve always returns a non-nil error and closes l.
+ * After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed].
+ */
+ serve(l: net.Listener): void
+ }
+ interface Server {
+ /**
+ * ServeTLS accepts incoming connections on the Listener l, creating a
+ * new service goroutine for each. The service goroutines perform TLS
+ * setup and then read requests, calling s.Handler to reply to them.
+ *
+ * Files containing a certificate and matching private key for the
+ * server must be provided if neither the [Server]'s
+ * TLSConfig.Certificates, TLSConfig.GetCertificate nor
+ * config.GetConfigForClient are populated.
+ * If the certificate is signed by a certificate authority, the
+ * certFile should be the concatenation of the server's certificate,
+ * any intermediates, and the CA's certificate.
+ *
+ * ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the
+ * returned error is [ErrServerClosed].
+ */
+ serveTLS(l: net.Listener, certFile: string, keyFile: string): void
+ }
+ interface Server {
+ /**
+ * SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
+ * By default, keep-alives are always enabled. Only very
+ * resource-constrained environments or servers in the process of
+ * shutting down should disable them.
+ */
+ setKeepAlivesEnabled(v: boolean): void
+ }
+ interface Server {
+ /**
+ * ListenAndServeTLS listens on the TCP network address s.Addr and
+ * then calls [ServeTLS] to handle requests on incoming TLS connections.
+ * Accepted connections are configured to enable TCP keep-alives.
+ *
+ * Filenames containing a certificate and matching private key for the
+ * server must be provided if neither the [Server]'s TLSConfig.Certificates
+ * nor TLSConfig.GetCertificate are populated. If the certificate is
+ * signed by a certificate authority, the certFile should be the
+ * concatenation of the server's certificate, any intermediates, and
+ * the CA's certificate.
+ *
+ * If s.Addr is blank, ":https" is used.
+ *
+ * ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or
+ * [Server.Close], the returned error is [ErrServerClosed].
+ */
+ listenAndServeTLS(certFile: string, keyFile: string): 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}).
+ *
+ * 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{}
+ interface JSONArray {
+ /**
+ * MarshalJSON implements the [json.Marshaler] interface.
+ */
+ marshalJSON(): string|Array
+ }
+ interface JSONArray {
+ /**
+ * String returns the string representation of the current json array.
+ */
+ string(): string
+ }
+ interface JSONArray {
+ /**
+ * Value implements the [driver.Valuer] interface.
+ */
+ value(): any
+ }
+ interface JSONArray {
+ /**
+ * Scan implements [sql.Scanner] interface to scan the provided value
+ * into the current JSONArray[T] instance.
+ */
+ scan(value: any): void
+ }
+ /**
+ * JSONMap defines a map that is safe for json and db read/write.
+ */
+ interface JSONMap extends _TygojaDict{}
+ interface JSONMap {
+ /**
+ * MarshalJSON implements the [json.Marshaler] interface.
+ */
+ marshalJSON(): string|Array
+ }
+ interface JSONMap {
+ /**
+ * String returns the string representation of the current json map.
+ */
+ string(): string
+ }
+ interface JSONMap {
+ /**
+ * Get retrieves a single value from the current JSONMap[T].
+ *
+ * This helper was added primarily to assist the goja integration since custom map types
+ * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods).
+ */
+ get(key: string): T
+ }
+ interface JSONMap {
+ /**
+ * Set sets a single value in the current JSONMap[T].
+ *
+ * This helper was added primarily to assist the goja integration since custom map types
+ * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods).
+ */
+ set(key: string, value: T): void
+ }
+ interface JSONMap {
+ /**
+ * Value implements the [driver.Valuer] interface.
+ */
+ value(): any
+ }
+ interface JSONMap {
+ /**
+ * Scan implements [sql.Scanner] interface to scan the provided value
+ * into the current JSONMap[T] instance.
+ */
+ scan(value: any): void
+ }
+ /**
+ * 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 auth {
+ /**
+ * @todo refactor and consider replace with a plain struct
+ *
+ * Provider defines a common interface for an OAuth2 client.
+ */
+ interface Provider {
+ [key:string]: any;
+ /**
+ * @todo temp backport
+ *
+ * Order returns the sorting order of the provider usually used in the auth methods list response.
+ */
+ logo(): string
+ /**
+ * @todo temp backport
+ *
+ * Order returns the sorting order of the provider usually used in the auth methods list response.
+ */
+ order(): number
+ /**
+ * Context returns the context associated with the provider (if any).
+ */
+ context(): context.Context
+ /**
+ * SetContext assigns the specified context to the current provider.
+ */
+ setContext(ctx: context.Context): void
+ /**
+ * PKCE indicates whether the provider can use the PKCE flow.
+ */
+ pkce(): boolean
+ /**
+ * SetPKCE toggles the state whether the provider can use the PKCE flow or not.
+ */
+ setPKCE(enable: boolean): void
+ /**
+ * DisplayName usually returns provider name as it is officially written
+ * and it could be used directly in the UI.
+ */
+ displayName(): string
+ /**
+ * SetDisplayName sets the provider's display name.
+ */
+ setDisplayName(displayName: string): void
+ /**
+ * Scopes returns the provider access permissions that will be requested.
+ */
+ scopes(): Array
+ /**
+ * SetScopes sets the provider access permissions that will be requested later.
+ */
+ setScopes(scopes: Array): void
+ /**
+ * ClientId returns the provider client's app ID.
+ */
+ clientId(): string
+ /**
+ * SetClientId sets the provider client's ID.
+ */
+ setClientId(clientId: string): void
+ /**
+ * ClientSecret returns the provider client's app secret.
+ */
+ clientSecret(): string
+ /**
+ * SetClientSecret sets the provider client's app secret.
+ */
+ setClientSecret(secret: string): void
+ /**
+ * RedirectURL returns the end address to redirect the user
+ * going through the OAuth flow.
+ */
+ redirectURL(): string
+ /**
+ * SetRedirectURL sets the provider's RedirectURL.
+ */
+ setRedirectURL(url: string): void
+ /**
+ * AuthURL returns the provider's authorization service url.
+ */
+ authURL(): string
+ /**
+ * SetAuthURL sets the provider's AuthURL.
+ */
+ setAuthURL(url: string): void
+ /**
+ * TokenURL returns the provider's token exchange service url.
+ */
+ tokenURL(): string
+ /**
+ * SetTokenURL sets the provider's TokenURL.
+ */
+ setTokenURL(url: string): void
+ /**
+ * UserInfoURL returns the provider's user info api url.
+ */
+ userInfoURL(): string
+ /**
+ * SetUserInfoURL sets the provider's UserInfoURL.
+ */
+ setUserInfoURL(url: string): void
+ /**
+ * Extra returns a shallow copy of any custom config data
+ * that the provider may need.
+ */
+ extra(): _TygojaDict
+ /**
+ * SetExtra updates the provider's custom config data.
+ */
+ setExtra(data: _TygojaDict): void
+ /**
+ * Client returns an http client using the provided token.
+ */
+ client(token: oauth2.Token): (any)
+ /**
+ * BuildAuthURL returns a URL to the provider's consent page
+ * that asks for permissions for the required scopes explicitly.
+ */
+ buildAuthURL(state: string, ...opts: oauth2.AuthCodeOption[]): string
+ /**
+ * FetchToken converts an authorization code to token.
+ */
+ fetchToken(code: string, ...opts: oauth2.AuthCodeOption[]): (oauth2.Token)
+ /**
+ * FetchRawUserInfo requests and marshalizes into `result` the
+ * the OAuth user api response.
+ */
+ fetchRawUserInfo(token: oauth2.Token): string|Array
+ /**
+ * FetchAuthUser is similar to FetchRawUserInfo, but normalizes and
+ * marshalizes the user api response into a standardized AuthUser struct.
+ */
+ fetchAuthUser(token: oauth2.Token): (AuthUser)
+ }
+ /**
+ * AuthUser defines a standardized OAuth2 user data structure.
+ */
+ interface AuthUser {
+ expiry: types.DateTime
+ rawUser: _TygojaDict
+ id: string
+ name: string
+ username: string
+ avatarURL: string
+ accessToken: string
+ refreshToken: string
+ /**
+ * The VERIFIED OAuth2 account email.
+ *
+ * It must be empty if the provider is not able to verify the email ownership.
+ */
+ email: string
+ /**
+ * @todo
+ * deprecated: use AvatarURL instead
+ * AvatarUrl will be removed after dropping v0.22 support
+ */
+ avatarUrl: string
+ }
+ interface AuthUser {
+ /**
+ * MarshalJSON implements the [json.Marshaler] interface.
+ *
+ * @todo remove after dropping v0.22 support
+ */
+ marshalJSON(): string|Array
+ }
+}
+
+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
+ * Hook event that you can embed in your custom typed event structs.
+ *
+ * Example:
+ *
+ * ```
+ * type CustomEvent struct {
+ * hook.Event
+ *
+ * SomeField int
+ * }
+ * ```
+ */
+ interface Event {
+ }
+ interface Event {
+ /**
+ * Next calls the next hook handler.
+ */
+ next(): void
+ }
+ /**
+ * Handler defines a single Hook handler.
+ * Multiple handlers can share the same id.
+ * If Id is not explicitly set it will be autogenerated by Hook.Add and Hook.AddHandler.
+ */
+ interface Handler {
+ /**
+ * Func defines the handler function to execute.
+ *
+ * Note that users need to call e.Next() in order to proceed with
+ * the execution of the hook chain.
+ */
+ func: (_arg0: T) => void
+ /**
+ * Id is the unique identifier of the handler.
+ *
+ * It could be used later to remove the handler from a hook via [Hook.Remove].
+ *
+ * If missing, an autogenerated value will be assigned when adding
+ * the handler to a hook.
+ */
+ id: string
+ /**
+ * Priority allows changing the default exec priority of the handler within a hook.
+ *
+ * If 0, the handler will be executed in the same order it was registered.
+ */
+ priority: number
+ }
+ /**
+ * Hook defines a generic concurrent safe structure for managing event hooks.
+ *
+ * When using custom event it must embed the base [hook.Event].
+ *
+ * Example:
+ *
+ * ```
+ * type CustomEvent struct {
+ * hook.Event
+ * SomeField int
+ * }
+ *
+ * h := Hook[*CustomEvent]{}
+ *
+ * h.BindFunc(func(e *CustomEvent) error {
+ * println(e.SomeField)
+ *
+ * return e.Next()
+ * })
+ *
+ * h.Trigger(&CustomEvent{ SomeField: 123 })
+ * ```
+ */
+ interface Hook {
+ }
+ interface Hook {
+ /**
+ * Bind registers the provided handler to the current hooks queue.
+ *
+ * If handler.Id is empty it is updated with autogenerated value.
+ *
+ * If a handler from the current hook list has Id matching handler.Id
+ * then the old handler is replaced with the new one.
+ */
+ bind(handler: Handler): string
+ }
+ interface Hook {
+ /**
+ * BindFunc is similar to Bind but registers a new handler from just the provided function.
+ *
+ * The registered handler is added with a default 0 priority and the id will be autogenerated.
+ *
+ * If you want to register a handler with custom priority or id use the [Hook.Bind] method.
+ */
+ bindFunc(fn: (e: T) => void): string
+ }
+ interface Hook {
+ /**
+ * Unbind removes one or many hook handler by their id.
+ */
+ unbind(...idsToRemove: string[]): void
+ }
+ interface Hook {
+ /**
+ * UnbindAll removes all registered handlers.
+ */
+ unbindAll(): void
+ }
+ interface Hook {
+ /**
+ * Length returns to total number of registered hook handlers.
+ */
+ length(): number
+ }
+ interface Hook {
+ /**
+ * Trigger executes all registered hook handlers one by one
+ * with the specified event as an argument.
+ *
+ * Optionally, this method allows also to register additional one off
+ * handler funcs that will be temporary appended to the handlers queue.
+ *
+ * NB! Each hook handler must call event.Next() in order the hook chain to proceed.
+ */
+ trigger(event: T, ...oneOffHandlerFuncs: ((_arg0: T) => void)[]): void
+ }
+ /**
+ * 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 _syyYiyB = mainHook
+ interface TaggedHook extends _syyYiyB {
+ }
+ interface TaggedHook {
+ /**
+ * CanTriggerOn checks if the current TaggedHook can be triggered with
+ * the provided event data tags.
+ *
+ * It returns always true if the hook doesn't have any tags.
+ */
+ canTriggerOn(tagsToCheck: Array): boolean
+ }
+ interface TaggedHook {
+ /**
+ * Bind registers the provided handler to the current hooks queue.
+ *
+ * It is similar to [Hook.Bind] with the difference that the handler
+ * function is invoked only if the event data tags satisfy h.CanTriggerOn.
+ */
+ bind(handler: Handler): string
+ }
+ interface TaggedHook {
+ /**
+ * BindFunc registers a new handler with the specified function.
+ *
+ * It is similar to [Hook.Bind] with the difference that the handler
+ * function is invoked only if the event data tags satisfy h.CanTriggerOn.
+ */
+ bindFunc(fn: (e: T) => void): string
+ }
+}
+
+/**
+ * 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.).
+ *
+ * NB!
+ * For compatibility with earlier PocketBase versions and to prevent
+ * unnecessary breaking changes, this package is based and implemented
+ * as a minimal, stripped down version of the previously used gocloud.dev/blob.
+ * While there is no promise that it won't diverge in the future to accommodate
+ * better some PocketBase specific use cases, currently it copies and
+ * tries to follow as close as possible the same implementations,
+ * conventions and rules for the key escaping/unescaping, blob read/write
+ * interfaces and struct options as gocloud.dev/blob, therefore the
+ * credits goes to the original Go Cloud Development Kit Authors.
+ */
+namespace blob {
+ /**
+ * ListObject represents a single blob returned from List.
+ */
+ interface ListObject {
+ /**
+ * Key is the key for this blob.
+ */
+ key: string
+ /**
+ * ModTime is the time the blob was last modified.
+ */
+ modTime: time.Time
+ /**
+ * Size is the size of the blob's content in bytes.
+ */
+ size: number
+ /**
+ * MD5 is an MD5 hash of the blob contents or nil if not available.
+ */
+ md5: string|Array
+ /**
+ * IsDir indicates that this result represents a "directory" in the
+ * hierarchical namespace, ending in ListOptions.Delimiter. Key can be
+ * passed as ListOptions.Prefix to list items in the "directory".
+ * Fields other than Key and IsDir will not be set if IsDir is true.
+ */
+ isDir: boolean
+ }
+ /**
+ * Attributes contains attributes about a blob.
+ */
+ interface Attributes {
+ /**
+ * CacheControl specifies caching attributes that services may use
+ * when serving the blob.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
+ */
+ cacheControl: string
+ /**
+ * ContentDisposition specifies whether the blob content is expected to be
+ * displayed inline or as an attachment.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
+ */
+ contentDisposition: string
+ /**
+ * ContentEncoding specifies the encoding used for the blob's content, if any.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
+ */
+ contentEncoding: string
+ /**
+ * ContentLanguage specifies the language used in the blob's content, if any.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language
+ */
+ contentLanguage: string
+ /**
+ * ContentType is the MIME type of the blob. It will not be empty.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
+ */
+ contentType: string
+ /**
+ * Metadata holds key/value pairs associated with the blob.
+ * Keys are guaranteed to be in lowercase, even if the backend service
+ * has case-sensitive keys (although note that Metadata written via
+ * this package will always be lowercased). If there are duplicate
+ * case-insensitive keys (e.g., "foo" and "FOO"), only one value
+ * will be kept, and it is undefined which one.
+ */
+ metadata: _TygojaDict
+ /**
+ * CreateTime is the time the blob was created, if available. If not available,
+ * CreateTime will be the zero time.
+ */
+ createTime: time.Time
+ /**
+ * ModTime is the time the blob was last modified.
+ */
+ modTime: time.Time
+ /**
+ * Size is the size of the blob's content in bytes.
+ */
+ size: number
+ /**
+ * MD5 is an MD5 hash of the blob contents or nil if not available.
+ */
+ md5: string|Array
+ /**
+ * ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag.
+ */
+ eTag: string
+ }
+ /**
+ * Reader reads bytes from a blob.
+ * It implements io.ReadSeekCloser, and must be closed after reads are finished.
+ */
+ interface Reader {
+ }
+ interface Reader {
+ /**
+ * Read implements io.Reader (https://golang.org/pkg/io/#Reader).
+ */
+ read(p: string|Array): number
+ }
+ interface Reader {
+ /**
+ * Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker).
+ */
+ seek(offset: number, whence: number): number
+ }
+ interface Reader {
+ /**
+ * Close implements io.Closer (https://golang.org/pkg/io/#Closer).
+ */
+ close(): void
+ }
+ interface Reader {
+ /**
+ * ContentType returns the MIME type of the blob.
+ */
+ contentType(): string
+ }
+ interface Reader {
+ /**
+ * ModTime returns the time the blob was last modified.
+ */
+ modTime(): time.Time
+ }
+ interface Reader {
+ /**
+ * Size returns the size of the blob content in bytes.
+ */
+ size(): number
+ }
+ interface Reader {
+ /**
+ * WriteTo reads from r and writes to w until there's no more data or
+ * an error occurs.
+ * The return value is the number of bytes written to w.
+ *
+ * It implements the io.WriterTo interface.
+ */
+ writeTo(w: io.Writer): number
+ }
+}
+
+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
+ /**
+ * NullFallback specify the preference for how NULL or empty values
+ * should be resolved (default to "auto").
+ *
+ * Set to NullFallbackDisabled to prevent any COALESCE or NULL fallbacks.
+ * Set to NullFallbackEnforced to prefer COALESCE or NULL fallbacks when needed.
+ */
+ nullFallback: NullFallbackPreference
+ /**
+ * 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?: MultiMatchSubquery
+ /**
+ * 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 _sZCZnSo = hook.Event
+ interface Event extends _sZCZnSo {
+ 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 _sdyWRKt = RouterGroup
+ interface Router extends _sdyWRKt {
+ }
+ interface Router {
+ /**
+ * BuildMux constructs a new mux [http.Handler] instance from the current router configurations.
+ */
+ buildMux(): http.Handler
+ }
+}
+
+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.
+ *
+ * See also the Dir field, which may set PWD in the environment.
+ */
+ 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.
+ *
+ * On Unix systems, the value of Dir also determines the
+ * child process's PWD environment variable if not otherwise
+ * specified. A Unix process represents its working directory
+ * not by name but as an implicit reference to a node in the
+ * file tree. So, if the child process obtains its working
+ * directory by calling a function such as C's getcwd, which
+ * computes the canonical name by walking up the file tree, it
+ * will not recover the original value of Dir if that value
+ * was an alias involving symbolic links. However, if the
+ * child process calls Go's [os.Getwd] or GNU C's
+ * get_current_dir_name, and the value of PWD is an alias for
+ * the current directory, those functions will return the
+ * value of PWD, which matches the value of Dir.
+ */
+ 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 and the returned error is of type
+ * [*ExitError], Output populates the Stderr field of the
+ * returned error.
+ */
+ 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
+ }
+}
+
+namespace mailer {
+ /**
+ * Message defines a generic email message struct.
+ */
+ 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
+ }
+ /**
+ * 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 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.
@@ -17848,3387 +21394,6 @@ namespace cobra {
}
}
-/**
- * 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 multipart implements MIME multipart parsing, as defined in RFC
- * 2046.
- *
- * The implementation is sufficient for HTTP (RFC 2388) and the multipart
- * bodies generated by popular browsers.
- *
- * # Limits
- *
- * To protect against malicious inputs, this package sets limits on the size
- * of the MIME data it processes.
- *
- * [Reader.NextPart] and [Reader.NextRawPart] limit the number of headers in a
- * part to 10000 and [Reader.ReadForm] limits the total number of headers in all
- * FileHeaders to 10000.
- * These limits may be adjusted with the GODEBUG=multipartmaxheaders=
- * setting.
- *
- * Reader.ReadForm further limits the number of parts in a form to 1000.
- * This limit may be adjusted with the GODEBUG=multipartmaxparts=
- * setting.
- */
-namespace multipart {
- /**
- * A FileHeader describes a file part of a multipart request.
- */
- interface FileHeader {
- filename: string
- header: textproto.MIMEHeader
- size: number
- }
- interface FileHeader {
- /**
- * Open opens and returns the [FileHeader]'s associated File.
- */
- open(): File
- }
-}
-
-/**
- * Package http provides HTTP client and server implementations.
- *
- * [Get], [Head], [Post], and [PostForm] make HTTP (or HTTPS) requests:
- *
- * ```
- * resp, err := http.Get("http://example.com/")
- * ...
- * resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
- * ...
- * resp, err := http.PostForm("http://example.com/form",
- * url.Values{"key": {"Value"}, "id": {"123"}})
- * ```
- *
- * The caller must close the response body when finished with it:
- *
- * ```
- * resp, err := http.Get("http://example.com/")
- * if err != nil {
- * // handle error
- * }
- * defer resp.Body.Close()
- * body, err := io.ReadAll(resp.Body)
- * // ...
- * ```
- *
- * # Clients and Transports
- *
- * For control over HTTP client headers, redirect policy, and other
- * settings, create a [Client]:
- *
- * ```
- * client := &http.Client{
- * CheckRedirect: redirectPolicyFunc,
- * }
- *
- * resp, err := client.Get("http://example.com")
- * // ...
- *
- * req, err := http.NewRequest("GET", "http://example.com", nil)
- * // ...
- * req.Header.Add("If-None-Match", `W/"wyzzy"`)
- * resp, err := client.Do(req)
- * // ...
- * ```
- *
- * For control over proxies, TLS configuration, keep-alives,
- * compression, and other settings, create a [Transport]:
- *
- * ```
- * tr := &http.Transport{
- * MaxIdleConns: 10,
- * IdleConnTimeout: 30 * time.Second,
- * DisableCompression: true,
- * }
- * client := &http.Client{Transport: tr}
- * resp, err := client.Get("https://example.com")
- * ```
- *
- * Clients and Transports are safe for concurrent use by multiple
- * goroutines and for efficiency should only be created once and re-used.
- *
- * # Servers
- *
- * ListenAndServe starts an HTTP server with a given address and handler.
- * The handler is usually nil, which means to use [DefaultServeMux].
- * [Handle] and [HandleFunc] add handlers to [DefaultServeMux]:
- *
- * ```
- * http.Handle("/foo", fooHandler)
- *
- * http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
- * fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
- * })
- *
- * log.Fatal(http.ListenAndServe(":8080", nil))
- * ```
- *
- * More control over the server's behavior is available by creating a
- * custom Server:
- *
- * ```
- * s := &http.Server{
- * Addr: ":8080",
- * Handler: myHandler,
- * ReadTimeout: 10 * time.Second,
- * WriteTimeout: 10 * time.Second,
- * MaxHeaderBytes: 1 << 20,
- * }
- * log.Fatal(s.ListenAndServe())
- * ```
- *
- * # HTTP/2
- *
- * Starting with Go 1.6, the http package has transparent support for the
- * HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2
- * can do so by setting [Transport.TLSNextProto] (for clients) or
- * [Server.TLSNextProto] (for servers) to a non-nil, empty
- * map. Alternatively, the following GODEBUG settings are
- * currently supported:
- *
- * ```
- * GODEBUG=http2client=0 # disable HTTP/2 client support
- * GODEBUG=http2server=0 # disable HTTP/2 server support
- * GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs
- * GODEBUG=http2debug=2 # ... even more verbose, with frame dumps
- * ```
- *
- * Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug
- *
- * The http package's [Transport] and [Server] both automatically enable
- * HTTP/2 support for simple configurations. To enable HTTP/2 for more
- * complex configurations, to use lower-level HTTP/2 features, or to use
- * a newer version of Go's http2 package, import "golang.org/x/net/http2"
- * directly and use its ConfigureTransport and/or ConfigureServer
- * functions. Manually configuring HTTP/2 via the golang.org/x/net/http2
- * package takes precedence over the net/http package's built-in HTTP/2
- * support.
- */
-namespace http {
- // @ts-ignore
- import mathrand = rand
- /**
- * PushOptions describes options for [Pusher.Push].
- */
- interface PushOptions {
- /**
- * Method specifies the HTTP method for the promised request.
- * If set, it must be "GET" or "HEAD". Empty means "GET".
- */
- method: string
- /**
- * Header specifies additional promised request headers. This cannot
- * include HTTP/2 pseudo header fields like ":path" and ":scheme",
- * which will be added automatically.
- */
- header: Header
- }
- // @ts-ignore
- import urlpkg = url
- /**
- * A Request represents an HTTP request received by a server
- * or to be sent by a client.
- *
- * The field semantics differ slightly between client and server
- * usage. In addition to the notes on the fields below, see the
- * documentation for [Request.Write] and [RoundTripper].
- */
- interface Request {
- /**
- * Method specifies the HTTP method (GET, POST, PUT, etc.).
- * For client requests, an empty string means GET.
- */
- method: string
- /**
- * URL specifies either the URI being requested (for server
- * requests) or the URL to access (for client requests).
- *
- * For server requests, the URL is parsed from the URI
- * supplied on the Request-Line as stored in RequestURI. For
- * most requests, fields other than Path and RawQuery will be
- * empty. (See RFC 7230, Section 5.3)
- *
- * For client requests, the URL's Host specifies the server to
- * connect to, while the Request's Host field optionally
- * specifies the Host header value to send in the HTTP
- * request.
- */
- url?: url.URL
- /**
- * The protocol version for incoming server requests.
- *
- * For client requests, these fields are ignored. The HTTP
- * client code always uses either HTTP/1.1 or HTTP/2.
- * See the docs on Transport for details.
- */
- proto: string // "HTTP/1.0"
- protoMajor: number // 1
- protoMinor: number // 0
- /**
- * Header contains the request header fields either received
- * by the server or to be sent by the client.
- *
- * If a server received a request with header lines,
- *
- * ```
- * Host: example.com
- * accept-encoding: gzip, deflate
- * Accept-Language: en-us
- * fOO: Bar
- * foo: two
- * ```
- *
- * then
- *
- * ```
- * Header = map[string][]string{
- * "Accept-Encoding": {"gzip, deflate"},
- * "Accept-Language": {"en-us"},
- * "Foo": {"Bar", "two"},
- * }
- * ```
- *
- * For incoming requests, the Host header is promoted to the
- * Request.Host field and removed from the Header map.
- *
- * HTTP defines that header names are case-insensitive. The
- * request parser implements this by using CanonicalHeaderKey,
- * making the first character and any characters following a
- * hyphen uppercase and the rest lowercase.
- *
- * For client requests, certain headers such as Content-Length
- * and Connection are automatically written when needed and
- * values in Header may be ignored. See the documentation
- * for the Request.Write method.
- */
- header: Header
- /**
- * Body is the request's body.
- *
- * For client requests, a nil body means the request has no
- * body, such as a GET request. The HTTP Client's Transport
- * is responsible for calling the Close method.
- *
- * For server requests, the Request Body is always non-nil
- * but will return EOF immediately when no body is present.
- * The Server will close the request body. The ServeHTTP
- * Handler does not need to.
- *
- * Body must allow Read to be called concurrently with Close.
- * In particular, calling Close should unblock a Read waiting
- * for input.
- */
- body: io.ReadCloser
- /**
- * GetBody defines an optional func to return a new copy of
- * Body. It is used for client requests when a redirect requires
- * reading the body more than once. Use of GetBody still
- * requires setting Body.
- *
- * For server requests, it is unused.
- */
- getBody: () => io.ReadCloser
- /**
- * ContentLength records the length of the associated content.
- * The value -1 indicates that the length is unknown.
- * Values >= 0 indicate that the given number of bytes may
- * be read from Body.
- *
- * For client requests, a value of 0 with a non-nil Body is
- * also treated as unknown.
- */
- contentLength: number
- /**
- * TransferEncoding lists the transfer encodings from outermost to
- * innermost. An empty list denotes the "identity" encoding.
- * TransferEncoding can usually be ignored; chunked encoding is
- * automatically added and removed as necessary when sending and
- * receiving requests.
- */
- transferEncoding: Array
- /**
- * Close indicates whether to close the connection after
- * replying to this request (for servers) or after sending this
- * request and reading its response (for clients).
- *
- * For server requests, the HTTP server handles this automatically
- * and this field is not needed by Handlers.
- *
- * For client requests, setting this field prevents re-use of
- * TCP connections between requests to the same hosts, as if
- * Transport.DisableKeepAlives were set.
- */
- close: boolean
- /**
- * For server requests, Host specifies the host on which the
- * URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this
- * is either the value of the "Host" header or the host name
- * given in the URL itself. For HTTP/2, it is the value of the
- * ":authority" pseudo-header field.
- * It may be of the form "host:port". For international domain
- * names, Host may be in Punycode or Unicode form. Use
- * golang.org/x/net/idna to convert it to either format if
- * needed.
- * To prevent DNS rebinding attacks, server Handlers should
- * validate that the Host header has a value for which the
- * Handler considers itself authoritative. The included
- * ServeMux supports patterns registered to particular host
- * names and thus protects its registered Handlers.
- *
- * For client requests, Host optionally overrides the Host
- * header to send. If empty, the Request.Write method uses
- * the value of URL.Host. Host may contain an international
- * domain name.
- */
- host: string
- /**
- * Form contains the parsed form data, including both the URL
- * field's query parameters and the PATCH, POST, or PUT form data.
- * This field is only available after ParseForm is called.
- * The HTTP client ignores Form and uses Body instead.
- */
- form: url.Values
- /**
- * PostForm contains the parsed form data from PATCH, POST
- * or PUT body parameters.
- *
- * This field is only available after ParseForm is called.
- * The HTTP client ignores PostForm and uses Body instead.
- */
- postForm: url.Values
- /**
- * MultipartForm is the parsed multipart form, including file uploads.
- * This field is only available after ParseMultipartForm is called.
- * The HTTP client ignores MultipartForm and uses Body instead.
- */
- multipartForm?: multipart.Form
- /**
- * Trailer specifies additional headers that are sent after the request
- * body.
- *
- * For server requests, the Trailer map initially contains only the
- * trailer keys, with nil values. (The client declares which trailers it
- * will later send.) While the handler is reading from Body, it must
- * not reference Trailer. After reading from Body returns EOF, Trailer
- * can be read again and will contain non-nil values, if they were sent
- * by the client.
- *
- * For client requests, Trailer must be initialized to a map containing
- * the trailer keys to later send. The values may be nil or their final
- * values. The ContentLength must be 0 or -1, to send a chunked request.
- * After the HTTP request is sent the map values can be updated while
- * the request body is read. Once the body returns EOF, the caller must
- * not mutate Trailer.
- *
- * Few HTTP clients, servers, or proxies support HTTP trailers.
- */
- trailer: Header
- /**
- * RemoteAddr allows HTTP servers and other software to record
- * the network address that sent the request, usually for
- * logging. This field is not filled in by ReadRequest and
- * has no defined format. The HTTP server in this package
- * sets RemoteAddr to an "IP:port" address before invoking a
- * handler.
- * This field is ignored by the HTTP client.
- */
- remoteAddr: string
- /**
- * RequestURI is the unmodified request-target of the
- * Request-Line (RFC 7230, Section 3.1.1) as sent by the client
- * to a server. Usually the URL field should be used instead.
- * It is an error to set this field in an HTTP client request.
- */
- requestURI: string
- /**
- * TLS allows HTTP servers and other software to record
- * information about the TLS connection on which the request
- * was received. This field is not filled in by ReadRequest.
- * The HTTP server in this package sets the field for
- * TLS-enabled connections before invoking a handler;
- * otherwise it leaves the field nil.
- * This field is ignored by the HTTP client.
- */
- tls?: any
- /**
- * Cancel is an optional channel whose closure indicates that the client
- * request should be regarded as canceled. Not all implementations of
- * RoundTripper may support Cancel.
- *
- * For server requests, this field is not applicable.
- *
- * Deprecated: Set the Request's context with NewRequestWithContext
- * instead. If a Request's Cancel field and context are both
- * set, it is undefined whether Cancel is respected.
- */
- cancel: undefined
- /**
- * Response is the redirect response which caused this request
- * to be created. This field is only populated during client
- * redirects.
- */
- response?: Response
- /**
- * Pattern is the [ServeMux] pattern that matched the request.
- * It is empty if the request was not matched against a pattern.
- */
- pattern: string
- }
- interface Request {
- /**
- * Context returns the request's context. To change the context, use
- * [Request.Clone] or [Request.WithContext].
- *
- * The returned context is always non-nil; it defaults to the
- * background context.
- *
- * For outgoing client requests, the context controls cancellation.
- *
- * For incoming server requests, the context is canceled when the
- * client's connection closes, the request is canceled (with HTTP/2),
- * or when the ServeHTTP method returns.
- */
- context(): context.Context
- }
- interface Request {
- /**
- * WithContext returns a shallow copy of r with its context changed
- * to ctx. The provided ctx must be non-nil.
- *
- * For outgoing client request, the context controls the entire
- * lifetime of a request and its response: obtaining a connection,
- * sending the request, and reading the response headers and body.
- *
- * To create a new request with a context, use [NewRequestWithContext].
- * To make a deep copy of a request with a new context, use [Request.Clone].
- */
- withContext(ctx: context.Context): (Request)
- }
- interface Request {
- /**
- * Clone returns a deep copy of r with its context changed to ctx.
- * The provided ctx must be non-nil.
- *
- * Clone only makes a shallow copy of the Body field.
- *
- * For an outgoing client request, the context controls the entire
- * lifetime of a request and its response: obtaining a connection,
- * sending the request, and reading the response headers and body.
- */
- clone(ctx: context.Context): (Request)
- }
- interface Request {
- /**
- * ProtoAtLeast reports whether the HTTP protocol used
- * in the request is at least major.minor.
- */
- protoAtLeast(major: number, minor: number): boolean
- }
- interface Request {
- /**
- * UserAgent returns the client's User-Agent, if sent in the request.
- */
- userAgent(): string
- }
- interface Request {
- /**
- * Cookies parses and returns the HTTP cookies sent with the request.
- */
- cookies(): Array<(Cookie | undefined)>
- }
- interface Request {
- /**
- * CookiesNamed parses and returns the named HTTP cookies sent with the request
- * or an empty slice if none matched.
- */
- cookiesNamed(name: string): Array<(Cookie | undefined)>
- }
- interface Request {
- /**
- * Cookie returns the named cookie provided in the request or
- * [ErrNoCookie] if not found.
- * If multiple cookies match the given name, only one cookie will
- * be returned.
- */
- cookie(name: string): (Cookie)
- }
- interface Request {
- /**
- * AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
- * AddCookie does not attach more than one [Cookie] header field. That
- * means all cookies, if any, are written into the same line,
- * separated by semicolon.
- * AddCookie only sanitizes c's name and value, and does not sanitize
- * a Cookie header already present in the request.
- */
- addCookie(c: Cookie): void
- }
- interface Request {
- /**
- * Referer returns the referring URL, if sent in the request.
- *
- * Referer is misspelled as in the request itself, a mistake from the
- * earliest days of HTTP. This value can also be fetched from the
- * [Header] map as Header["Referer"]; the benefit of making it available
- * as a method is that the compiler can diagnose programs that use the
- * alternate (correct English) spelling req.Referrer() but cannot
- * diagnose programs that use Header["Referrer"].
- */
- referer(): string
- }
- interface Request {
- /**
- * MultipartReader returns a MIME multipart reader if this is a
- * multipart/form-data or a multipart/mixed POST request, else returns nil and an error.
- * Use this function instead of [Request.ParseMultipartForm] to
- * process the request body as a stream.
- */
- multipartReader(): (multipart.Reader)
- }
- interface Request {
- /**
- * Write writes an HTTP/1.1 request, which is the header and body, in wire format.
- * This method consults the following fields of the request:
- *
- * ```
- * Host
- * URL
- * Method (defaults to "GET")
- * Header
- * ContentLength
- * TransferEncoding
- * Body
- * ```
- *
- * If Body is present, Content-Length is <= 0 and [Request.TransferEncoding]
- * hasn't been set to "identity", Write adds "Transfer-Encoding:
- * chunked" to the header. Body is closed after it is sent.
- */
- write(w: io.Writer): void
- }
- interface Request {
- /**
- * WriteProxy is like [Request.Write] but writes the request in the form
- * expected by an HTTP proxy. In particular, [Request.WriteProxy] writes the
- * initial Request-URI line of the request with an absolute URI, per
- * section 5.3 of RFC 7230, including the scheme and host.
- * In either case, WriteProxy also writes a Host header, using
- * either r.Host or r.URL.Host.
- */
- writeProxy(w: io.Writer): void
- }
- interface Request {
- /**
- * BasicAuth returns the username and password provided in the request's
- * Authorization header, if the request uses HTTP Basic Authentication.
- * See RFC 2617, Section 2.
- */
- basicAuth(): [string, string, boolean]
- }
- interface Request {
- /**
- * SetBasicAuth sets the request's Authorization header to use HTTP
- * Basic Authentication with the provided username and password.
- *
- * With HTTP Basic Authentication the provided username and password
- * are not encrypted. It should generally only be used in an HTTPS
- * request.
- *
- * The username may not contain a colon. Some protocols may impose
- * additional requirements on pre-escaping the username and
- * password. For instance, when used with OAuth2, both arguments must
- * be URL encoded first with [url.QueryEscape].
- */
- setBasicAuth(username: string, password: string): void
- }
- interface Request {
- /**
- * ParseForm populates r.Form and r.PostForm.
- *
- * For all requests, ParseForm parses the raw query from the URL and updates
- * r.Form.
- *
- * For POST, PUT, and PATCH requests, it also reads the request body, parses it
- * as a form and puts the results into both r.PostForm and r.Form. Request body
- * parameters take precedence over URL query string values in r.Form.
- *
- * If the request Body's size has not already been limited by [MaxBytesReader],
- * the size is capped at 10MB.
- *
- * For other HTTP methods, or when the Content-Type is not
- * application/x-www-form-urlencoded, the request Body is not read, and
- * r.PostForm is initialized to a non-nil, empty value.
- *
- * [Request.ParseMultipartForm] calls ParseForm automatically.
- * ParseForm is idempotent.
- */
- parseForm(): void
- }
- interface Request {
- /**
- * ParseMultipartForm parses a request body as multipart/form-data.
- * The whole request body is parsed and up to a total of maxMemory bytes of
- * its file parts are stored in memory, with the remainder stored on
- * disk in temporary files.
- * ParseMultipartForm calls [Request.ParseForm] if necessary.
- * If ParseForm returns an error, ParseMultipartForm returns it but also
- * continues parsing the request body.
- * After one call to ParseMultipartForm, subsequent calls have no effect.
- */
- parseMultipartForm(maxMemory: number): void
- }
- interface Request {
- /**
- * FormValue returns the first value for the named component of the query.
- * The precedence order:
- * 1. application/x-www-form-urlencoded form body (POST, PUT, PATCH only)
- * 2. query parameters (always)
- * 3. multipart/form-data form body (always)
- *
- * FormValue calls [Request.ParseMultipartForm] and [Request.ParseForm]
- * if necessary and ignores any errors returned by these functions.
- * If key is not present, FormValue returns the empty string.
- * To access multiple values of the same key, call ParseForm and
- * then inspect [Request.Form] directly.
- */
- formValue(key: string): string
- }
- interface Request {
- /**
- * PostFormValue returns the first value for the named component of the POST,
- * PUT, or PATCH request body. URL query parameters are ignored.
- * PostFormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary and ignores
- * any errors returned by these functions.
- * If key is not present, PostFormValue returns the empty string.
- */
- postFormValue(key: string): string
- }
- interface Request {
- /**
- * FormFile returns the first file for the provided form key.
- * FormFile calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary.
- */
- formFile(key: string): [multipart.File, (multipart.FileHeader)]
- }
- interface Request {
- /**
- * PathValue returns the value for the named path wildcard in the [ServeMux] pattern
- * that matched the request.
- * It returns the empty string if the request was not matched against a pattern
- * or there is no such wildcard in the pattern.
- */
- pathValue(name: string): string
- }
- interface Request {
- /**
- * SetPathValue sets name to value, so that subsequent calls to r.PathValue(name)
- * return value.
- */
- setPathValue(name: string, value: string): void
- }
- /**
- * A Handler responds to an HTTP request.
- *
- * [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter]
- * and then return. Returning signals that the request is finished; it
- * is not valid to use the [ResponseWriter] or read from the
- * [Request.Body] after or concurrently with the completion of the
- * ServeHTTP call.
- *
- * Depending on the HTTP client software, HTTP protocol version, and
- * any intermediaries between the client and the Go server, it may not
- * be possible to read from the [Request.Body] after writing to the
- * [ResponseWriter]. Cautious handlers should read the [Request.Body]
- * first, and then reply.
- *
- * Except for reading the body, handlers should not modify the
- * provided Request.
- *
- * If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
- * that the effect of the panic was isolated to the active request.
- * It recovers the panic, logs a stack trace to the server error log,
- * and either closes the network connection or sends an HTTP/2
- * RST_STREAM, depending on the HTTP protocol. To abort a handler so
- * the client sees an interrupted response but the server doesn't log
- * an error, panic with the value [ErrAbortHandler].
- */
- interface Handler {
- [key:string]: any;
- serveHTTP(_arg0: ResponseWriter, _arg1: Request): void
- }
- /**
- * A ResponseWriter interface is used by an HTTP handler to
- * construct an HTTP response.
- *
- * A ResponseWriter may not be used after [Handler.ServeHTTP] has returned.
- */
- interface ResponseWriter {
- [key:string]: any;
- /**
- * Header returns the header map that will be sent by
- * [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which
- * [Handler] implementations can set HTTP trailers.
- *
- * Changing the header map after a call to [ResponseWriter.WriteHeader] (or
- * [ResponseWriter.Write]) has no effect unless the HTTP status code was of the
- * 1xx class or the modified headers are trailers.
- *
- * There are two ways to set Trailers. The preferred way is to
- * predeclare in the headers which trailers you will later
- * send by setting the "Trailer" header to the names of the
- * trailer keys which will come later. In this case, those
- * keys of the Header map are treated as if they were
- * trailers. See the example. The second way, for trailer
- * keys not known to the [Handler] until after the first [ResponseWriter.Write],
- * is to prefix the [Header] map keys with the [TrailerPrefix]
- * constant value.
- *
- * To suppress automatic response headers (such as "Date"), set
- * their value to nil.
- */
- header(): Header
- /**
- * Write writes the data to the connection as part of an HTTP reply.
- *
- * If [ResponseWriter.WriteHeader] has not yet been called, Write calls
- * WriteHeader(http.StatusOK) before writing the data. If the Header
- * does not contain a Content-Type line, Write adds a Content-Type set
- * to the result of passing the initial 512 bytes of written data to
- * [DetectContentType]. Additionally, if the total size of all written
- * data is under a few KB and there are no Flush calls, the
- * Content-Length header is added automatically.
- *
- * Depending on the HTTP protocol version and the client, calling
- * Write or WriteHeader may prevent future reads on the
- * Request.Body. For HTTP/1.x requests, handlers should read any
- * needed request body data before writing the response. Once the
- * headers have been flushed (due to either an explicit Flusher.Flush
- * call or writing enough data to trigger a flush), the request body
- * may be unavailable. For HTTP/2 requests, the Go HTTP server permits
- * handlers to continue to read the request body while concurrently
- * writing the response. However, such behavior may not be supported
- * by all HTTP/2 clients. Handlers should read before writing if
- * possible to maximize compatibility.
- */
- write(_arg0: string|Array): number
- /**
- * WriteHeader sends an HTTP response header with the provided
- * status code.
- *
- * If WriteHeader is not called explicitly, the first call to Write
- * will trigger an implicit WriteHeader(http.StatusOK).
- * Thus explicit calls to WriteHeader are mainly used to
- * send error codes or 1xx informational responses.
- *
- * The provided code must be a valid HTTP 1xx-5xx status code.
- * Any number of 1xx headers may be written, followed by at most
- * one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx
- * headers may be buffered. Use the Flusher interface to send
- * buffered data. The header map is cleared when 2xx-5xx headers are
- * sent, but not with 1xx headers.
- *
- * The server will automatically send a 100 (Continue) header
- * on the first read from the request body if the request has
- * an "Expect: 100-continue" header.
- */
- writeHeader(statusCode: number): void
- }
- /**
- * A Server defines parameters for running an HTTP server.
- * The zero value for Server is a valid configuration.
- */
- interface Server {
- /**
- * Addr optionally specifies the TCP address for the server to listen on,
- * in the form "host:port". If empty, ":http" (port 80) is used.
- * The service names are defined in RFC 6335 and assigned by IANA.
- * See net.Dial for details of the address format.
- */
- addr: string
- handler: Handler // handler to invoke, http.DefaultServeMux if nil
- /**
- * DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
- * otherwise responds with 200 OK and Content-Length: 0.
- */
- disableGeneralOptionsHandler: boolean
- /**
- * TLSConfig optionally provides a TLS configuration for use
- * by ServeTLS and ListenAndServeTLS. Note that this value is
- * cloned by ServeTLS and ListenAndServeTLS, so it's not
- * possible to modify the configuration with methods like
- * tls.Config.SetSessionTicketKeys. To use
- * SetSessionTicketKeys, use Server.Serve with a TLS Listener
- * instead.
- */
- tlsConfig?: any
- /**
- * ReadTimeout is the maximum duration for reading the entire
- * request, including the body. A zero or negative value means
- * there will be no timeout.
- *
- * Because ReadTimeout does not let Handlers make per-request
- * decisions on each request body's acceptable deadline or
- * upload rate, most users will prefer to use
- * ReadHeaderTimeout. It is valid to use them both.
- */
- readTimeout: time.Duration
- /**
- * ReadHeaderTimeout is the amount of time allowed to read
- * request headers. The connection's read deadline is reset
- * after reading the headers and the Handler can decide what
- * is considered too slow for the body. If zero, the value of
- * ReadTimeout is used. If negative, or if zero and ReadTimeout
- * is zero or negative, there is no timeout.
- */
- readHeaderTimeout: time.Duration
- /**
- * WriteTimeout is the maximum duration before timing out
- * writes of the response. It is reset whenever a new
- * request's header is read. Like ReadTimeout, it does not
- * let Handlers make decisions on a per-request basis.
- * A zero or negative value means there will be no timeout.
- */
- writeTimeout: time.Duration
- /**
- * IdleTimeout is the maximum amount of time to wait for the
- * next request when keep-alives are enabled. If zero, the value
- * of ReadTimeout is used. If negative, or if zero and ReadTimeout
- * is zero or negative, there is no timeout.
- */
- idleTimeout: time.Duration
- /**
- * MaxHeaderBytes controls the maximum number of bytes the
- * server will read parsing the request header's keys and
- * values, including the request line. It does not limit the
- * size of the request body.
- * If zero, DefaultMaxHeaderBytes is used.
- */
- maxHeaderBytes: number
- /**
- * TLSNextProto optionally specifies a function to take over
- * ownership of the provided TLS connection when an ALPN
- * protocol upgrade has occurred. The map key is the protocol
- * name negotiated. The Handler argument should be used to
- * handle HTTP requests and will initialize the Request's TLS
- * and RemoteAddr if not already set. The connection is
- * automatically closed when the function returns.
- * If TLSNextProto is not nil, HTTP/2 support is not enabled
- * automatically.
- */
- tlsNextProto: _TygojaDict
- /**
- * ConnState specifies an optional callback function that is
- * called when a client connection changes state. See the
- * ConnState type and associated constants for details.
- */
- connState: (_arg0: net.Conn, _arg1: ConnState) => void
- /**
- * ErrorLog specifies an optional logger for errors accepting
- * connections, unexpected behavior from handlers, and
- * underlying FileSystem errors.
- * If nil, logging is done via the log package's standard logger.
- */
- errorLog?: any
- /**
- * BaseContext optionally specifies a function that returns
- * the base context for incoming requests on this server.
- * The provided Listener is the specific Listener that's
- * about to start accepting requests.
- * If BaseContext is nil, the default is context.Background().
- * If non-nil, it must return a non-nil context.
- */
- baseContext: (_arg0: net.Listener) => context.Context
- /**
- * ConnContext optionally specifies a function that modifies
- * the context used for a new connection c. The provided ctx
- * is derived from the base context and has a ServerContextKey
- * value.
- */
- connContext: (ctx: context.Context, c: net.Conn) => context.Context
- /**
- * HTTP2 configures HTTP/2 connections.
- *
- * This field does not yet have any effect.
- * See https://go.dev/issue/67813.
- */
- http2?: HTTP2Config
- /**
- * Protocols is the set of protocols accepted by the server.
- *
- * If Protocols includes UnencryptedHTTP2, the server will accept
- * unencrypted HTTP/2 connections. The server can serve both
- * HTTP/1 and unencrypted HTTP/2 on the same address and port.
- *
- * If Protocols is nil, the default is usually HTTP/1 and HTTP/2.
- * If TLSNextProto is non-nil and does not contain an "h2" entry,
- * the default is HTTP/1 only.
- */
- protocols?: Protocols
- }
- interface Server {
- /**
- * Close immediately closes all active net.Listeners and any
- * connections in state [StateNew], [StateActive], or [StateIdle]. For a
- * graceful shutdown, use [Server.Shutdown].
- *
- * Close does not attempt to close (and does not even know about)
- * any hijacked connections, such as WebSockets.
- *
- * Close returns any error returned from closing the [Server]'s
- * underlying Listener(s).
- */
- close(): void
- }
- interface Server {
- /**
- * Shutdown gracefully shuts down the server without interrupting any
- * active connections. Shutdown works by first closing all open
- * listeners, then closing all idle connections, and then waiting
- * indefinitely for connections to return to idle and then shut down.
- * If the provided context expires before the shutdown is complete,
- * Shutdown returns the context's error, otherwise it returns any
- * error returned from closing the [Server]'s underlying Listener(s).
- *
- * When Shutdown is called, [Serve], [ServeTLS], [ListenAndServe], and
- * [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the
- * program doesn't exit and waits instead for Shutdown to return.
- *
- * Shutdown does not attempt to close nor wait for hijacked
- * connections such as WebSockets. The caller of Shutdown should
- * separately notify such long-lived connections of shutdown and wait
- * for them to close, if desired. See [Server.RegisterOnShutdown] for a way to
- * register shutdown notification functions.
- *
- * Once Shutdown has been called on a server, it may not be reused;
- * future calls to methods such as Serve will return ErrServerClosed.
- */
- shutdown(ctx: context.Context): void
- }
- interface Server {
- /**
- * RegisterOnShutdown registers a function to call on [Server.Shutdown].
- * This can be used to gracefully shutdown connections that have
- * undergone ALPN protocol upgrade or that have been hijacked.
- * This function should start protocol-specific graceful shutdown,
- * but should not wait for shutdown to complete.
- */
- registerOnShutdown(f: () => void): void
- }
- interface Server {
- /**
- * ListenAndServe listens on the TCP network address s.Addr and then
- * calls [Serve] to handle requests on incoming connections.
- * Accepted connections are configured to enable TCP keep-alives.
- *
- * If s.Addr is blank, ":http" is used.
- *
- * ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close],
- * the returned error is [ErrServerClosed].
- */
- listenAndServe(): void
- }
- interface Server {
- /**
- * Serve accepts incoming connections on the Listener l, creating a
- * new service goroutine for each. The service goroutines read requests and
- * then call s.Handler to reply to them.
- *
- * HTTP/2 support is only enabled if the Listener returns [*tls.Conn]
- * connections and they were configured with "h2" in the TLS
- * Config.NextProtos.
- *
- * Serve always returns a non-nil error and closes l.
- * After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed].
- */
- serve(l: net.Listener): void
- }
- interface Server {
- /**
- * ServeTLS accepts incoming connections on the Listener l, creating a
- * new service goroutine for each. The service goroutines perform TLS
- * setup and then read requests, calling s.Handler to reply to them.
- *
- * Files containing a certificate and matching private key for the
- * server must be provided if neither the [Server]'s
- * TLSConfig.Certificates, TLSConfig.GetCertificate nor
- * config.GetConfigForClient are populated.
- * If the certificate is signed by a certificate authority, the
- * certFile should be the concatenation of the server's certificate,
- * any intermediates, and the CA's certificate.
- *
- * ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the
- * returned error is [ErrServerClosed].
- */
- serveTLS(l: net.Listener, certFile: string, keyFile: string): void
- }
- interface Server {
- /**
- * SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
- * By default, keep-alives are always enabled. Only very
- * resource-constrained environments or servers in the process of
- * shutting down should disable them.
- */
- setKeepAlivesEnabled(v: boolean): void
- }
- interface Server {
- /**
- * ListenAndServeTLS listens on the TCP network address s.Addr and
- * then calls [ServeTLS] to handle requests on incoming TLS connections.
- * Accepted connections are configured to enable TCP keep-alives.
- *
- * Filenames containing a certificate and matching private key for the
- * server must be provided if neither the [Server]'s TLSConfig.Certificates
- * nor TLSConfig.GetCertificate are populated. If the certificate is
- * signed by a certificate authority, the certFile should be the
- * concatenation of the server's certificate, any intermediates, and
- * the CA's certificate.
- *
- * If s.Addr is blank, ":https" is used.
- *
- * ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or
- * [Server.Close], the returned error is [ErrServerClosed].
- */
- listenAndServeTLS(certFile: string, keyFile: string): void
- }
-}
-
-/**
- * Package blob defines a lightweight abstration for interacting with
- * various storage services (local filesystem, S3, etc.).
- *
- * NB!
- * For compatibility with earlier PocketBase versions and to prevent
- * unnecessary breaking changes, this package is based and implemented
- * as a minimal, stripped down version of the previously used gocloud.dev/blob.
- * While there is no promise that it won't diverge in the future to accommodate
- * better some PocketBase specific use cases, currently it copies and
- * tries to follow as close as possible the same implementations,
- * conventions and rules for the key escaping/unescaping, blob read/write
- * interfaces and struct options as gocloud.dev/blob, therefore the
- * credits goes to the original Go Cloud Development Kit Authors.
- */
-namespace blob {
- /**
- * ListObject represents a single blob returned from List.
- */
- interface ListObject {
- /**
- * Key is the key for this blob.
- */
- key: string
- /**
- * ModTime is the time the blob was last modified.
- */
- modTime: time.Time
- /**
- * Size is the size of the blob's content in bytes.
- */
- size: number
- /**
- * MD5 is an MD5 hash of the blob contents or nil if not available.
- */
- md5: string|Array
- /**
- * IsDir indicates that this result represents a "directory" in the
- * hierarchical namespace, ending in ListOptions.Delimiter. Key can be
- * passed as ListOptions.Prefix to list items in the "directory".
- * Fields other than Key and IsDir will not be set if IsDir is true.
- */
- isDir: boolean
- }
- /**
- * Attributes contains attributes about a blob.
- */
- interface Attributes {
- /**
- * CacheControl specifies caching attributes that services may use
- * when serving the blob.
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
- */
- cacheControl: string
- /**
- * ContentDisposition specifies whether the blob content is expected to be
- * displayed inline or as an attachment.
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
- */
- contentDisposition: string
- /**
- * ContentEncoding specifies the encoding used for the blob's content, if any.
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
- */
- contentEncoding: string
- /**
- * ContentLanguage specifies the language used in the blob's content, if any.
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language
- */
- contentLanguage: string
- /**
- * ContentType is the MIME type of the blob. It will not be empty.
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
- */
- contentType: string
- /**
- * Metadata holds key/value pairs associated with the blob.
- * Keys are guaranteed to be in lowercase, even if the backend service
- * has case-sensitive keys (although note that Metadata written via
- * this package will always be lowercased). If there are duplicate
- * case-insensitive keys (e.g., "foo" and "FOO"), only one value
- * will be kept, and it is undefined which one.
- */
- metadata: _TygojaDict
- /**
- * CreateTime is the time the blob was created, if available. If not available,
- * CreateTime will be the zero time.
- */
- createTime: time.Time
- /**
- * ModTime is the time the blob was last modified.
- */
- modTime: time.Time
- /**
- * Size is the size of the blob's content in bytes.
- */
- size: number
- /**
- * MD5 is an MD5 hash of the blob contents or nil if not available.
- */
- md5: string|Array
- /**
- * ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag.
- */
- eTag: string
- }
- /**
- * Reader reads bytes from a blob.
- * It implements io.ReadSeekCloser, and must be closed after reads are finished.
- */
- interface Reader {
- }
- interface Reader {
- /**
- * Read implements io.Reader (https://golang.org/pkg/io/#Reader).
- */
- read(p: string|Array): number
- }
- interface Reader {
- /**
- * Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker).
- */
- seek(offset: number, whence: number): number
- }
- interface Reader {
- /**
- * Close implements io.Closer (https://golang.org/pkg/io/#Closer).
- */
- close(): void
- }
- interface Reader {
- /**
- * ContentType returns the MIME type of the blob.
- */
- contentType(): string
- }
- interface Reader {
- /**
- * ModTime returns the time the blob was last modified.
- */
- modTime(): time.Time
- }
- interface Reader {
- /**
- * Size returns the size of the blob content in bytes.
- */
- size(): number
- }
- interface Reader {
- /**
- * WriteTo reads from r and writes to w until there's no more data or
- * an error occurs.
- * The return value is the number of bytes written to w.
- *
- * It implements the io.WriterTo interface.
- */
- writeTo(w: io.Writer): 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 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]any 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
- }
-}
-
-namespace hook {
- /**
- * Event implements [Resolver] and it is intended to be used as a base
- * Hook event that you can embed in your custom typed event structs.
- *
- * Example:
- *
- * ```
- * type CustomEvent struct {
- * hook.Event
- *
- * SomeField int
- * }
- * ```
- */
- interface Event {
- }
- interface Event {
- /**
- * Next calls the next hook handler.
- */
- next(): void
- }
- /**
- * Handler defines a single Hook handler.
- * Multiple handlers can share the same id.
- * If Id is not explicitly set it will be autogenerated by Hook.Add and Hook.AddHandler.
- */
- interface Handler {
- /**
- * Func defines the handler function to execute.
- *
- * Note that users need to call e.Next() in order to proceed with
- * the execution of the hook chain.
- */
- func: (_arg0: T) => void
- /**
- * Id is the unique identifier of the handler.
- *
- * It could be used later to remove the handler from a hook via [Hook.Remove].
- *
- * If missing, an autogenerated value will be assigned when adding
- * the handler to a hook.
- */
- id: string
- /**
- * Priority allows changing the default exec priority of the handler within a hook.
- *
- * If 0, the handler will be executed in the same order it was registered.
- */
- priority: number
- }
- /**
- * Hook defines a generic concurrent safe structure for managing event hooks.
- *
- * When using custom event it must embed the base [hook.Event].
- *
- * Example:
- *
- * ```
- * type CustomEvent struct {
- * hook.Event
- * SomeField int
- * }
- *
- * h := Hook[*CustomEvent]{}
- *
- * h.BindFunc(func(e *CustomEvent) error {
- * println(e.SomeField)
- *
- * return e.Next()
- * })
- *
- * h.Trigger(&CustomEvent{ SomeField: 123 })
- * ```
- */
- interface Hook {
- }
- interface Hook {
- /**
- * Bind registers the provided handler to the current hooks queue.
- *
- * If handler.Id is empty it is updated with autogenerated value.
- *
- * If a handler from the current hook list has Id matching handler.Id
- * then the old handler is replaced with the new one.
- */
- bind(handler: Handler): string
- }
- interface Hook {
- /**
- * BindFunc is similar to Bind but registers a new handler from just the provided function.
- *
- * The registered handler is added with a default 0 priority and the id will be autogenerated.
- *
- * If you want to register a handler with custom priority or id use the [Hook.Bind] method.
- */
- bindFunc(fn: (e: T) => void): string
- }
- interface Hook {
- /**
- * Unbind removes one or many hook handler by their id.
- */
- unbind(...idsToRemove: string[]): void
- }
- interface Hook {
- /**
- * UnbindAll removes all registered handlers.
- */
- unbindAll(): void
- }
- interface Hook {
- /**
- * Length returns to total number of registered hook handlers.
- */
- length(): number
- }
- interface Hook {
- /**
- * Trigger executes all registered hook handlers one by one
- * with the specified event as an argument.
- *
- * Optionally, this method allows also to register additional one off
- * handler funcs that will be temporary appended to the handlers queue.
- *
- * NB! Each hook handler must call event.Next() in order the hook chain to proceed.
- */
- trigger(event: T, ...oneOffHandlerFuncs: ((_arg0: T) => void)[]): void
- }
- /**
- * 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 _sboxsdB = mainHook
- interface TaggedHook extends _sboxsdB {
- }
- interface TaggedHook {
- /**
- * CanTriggerOn checks if the current TaggedHook can be triggered with
- * the provided event data tags.
- *
- * It returns always true if the hook doesn't have any tags.
- */
- canTriggerOn(tagsToCheck: Array): boolean
- }
- interface TaggedHook {
- /**
- * Bind registers the provided handler to the current hooks queue.
- *
- * It is similar to [Hook.Bind] with the difference that the handler
- * function is invoked only if the event data tags satisfy h.CanTriggerOn.
- */
- bind(handler: Handler): string
- }
- interface TaggedHook {
- /**
- * BindFunc registers a new handler with the specified function.
- *
- * It is similar to [Hook.Bind] with the difference that the handler
- * function is invoked only if the event data tags satisfy h.CanTriggerOn.
- */
- bindFunc(fn: (e: T) => void): string
- }
-}
-
-/**
- * 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{}
- interface JSONArray {
- /**
- * MarshalJSON implements the [json.Marshaler] interface.
- */
- marshalJSON(): string|Array
- }
- interface JSONArray {
- /**
- * String returns the string representation of the current json array.
- */
- string(): string
- }
- interface JSONArray {
- /**
- * Value implements the [driver.Valuer] interface.
- */
- value(): any
- }
- interface JSONArray {
- /**
- * Scan implements [sql.Scanner] interface to scan the provided value
- * into the current JSONArray[T] instance.
- */
- scan(value: any): void
- }
- /**
- * JSONMap defines a map that is safe for json and db read/write.
- */
- interface JSONMap extends _TygojaDict{}
- interface JSONMap {
- /**
- * MarshalJSON implements the [json.Marshaler] interface.
- */
- marshalJSON(): string|Array
- }
- interface JSONMap {
- /**
- * String returns the string representation of the current json map.
- */
- string(): string
- }
- interface JSONMap {
- /**
- * Get retrieves a single value from the current JSONMap[T].
- *
- * This helper was added primarily to assist the goja integration since custom map types
- * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods).
- */
- get(key: string): T
- }
- interface JSONMap {
- /**
- * Set sets a single value in the current JSONMap[T].
- *
- * This helper was added primarily to assist the goja integration since custom map types
- * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods).
- */
- set(key: string, value: T): void
- }
- interface JSONMap {
- /**
- * Value implements the [driver.Valuer] interface.
- */
- value(): any
- }
- interface JSONMap {
- /**
- * Scan implements [sql.Scanner] interface to scan the provided value
- * into the current JSONMap[T] instance.
- */
- scan(value: any): void
- }
- /**
- * 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
- /**
- * NullFallback specify the preference for how NULL or empty values
- * should be resolved (default to "auto").
- *
- * Set to NullFallbackDisabled to prevent any COALESCE or NULL fallbacks.
- * Set to NullFallbackEnforced to prefer COALESCE or NULL fallbacks when needed.
- */
- nullFallback: NullFallbackPreference
- /**
- * 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?: MultiMatchSubquery
- /**
- * 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 _sbkZyQr = hook.Event
- interface Event extends _sbkZyQr {
- 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 _sDUkutP = RouterGroup
- interface Router extends _sDUkutP {
- }
- interface Router {
- /**
- * BuildMux constructs a new mux [http.Handler] instance from the current router configurations.
- */
- buildMux(): http.Handler
- }
-}
-
-/**
- * Package cron implements a crontab-like service to execute and schedule
- * repeative tasks/jobs.
- *
- * Example:
- *
- * ```
- * c := cron.New()
- * c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
- * c.Start()
- * ```
- */
-namespace cron {
- /**
- * Cron is a crontab-like struct for tasks/jobs scheduling.
- */
- interface Cron {
- }
- interface Cron {
- /**
- * SetInterval changes the current cron tick interval
- * (it usually should be >= 1 minute).
- */
- setInterval(d: time.Duration): void
- }
- interface Cron {
- /**
- * SetTimezone changes the current cron tick timezone.
- */
- setTimezone(l: time.Location): void
- }
- interface Cron {
- /**
- * MustAdd is similar to Add() but panic on failure.
- */
- mustAdd(jobId: string, cronExpr: string, run: () => void): void
- }
- interface Cron {
- /**
- * Add registers a single cron job.
- *
- * If there is already a job with the provided id, then the old job
- * will be replaced with the new one.
- *
- * cronExpr is a regular cron expression, eg. "0 *\/3 * * *" (aka. at minute 0 past every 3rd hour).
- * Check cron.NewSchedule() for the supported tokens.
- */
- add(jobId: string, cronExpr: string, fn: () => void): void
- }
- interface Cron {
- /**
- * Remove removes a single cron job by its id.
- */
- remove(jobId: string): void
- }
- interface Cron {
- /**
- * RemoveAll removes all registered cron jobs.
- */
- removeAll(): void
- }
- interface Cron {
- /**
- * Total returns the current total number of registered cron jobs.
- */
- total(): number
- }
- interface Cron {
- /**
- * Jobs returns a shallow copy of the currently registered cron jobs.
- */
- jobs(): Array<(Job | undefined)>
- }
- interface Cron {
- /**
- * Stop stops the current cron ticker (if not already).
- *
- * You can resume the ticker by calling Start().
- */
- stop(): void
- }
- interface Cron {
- /**
- * Start starts the cron ticker.
- *
- * Calling Start() on already started cron will restart the ticker.
- */
- start(): void
- }
- interface Cron {
- /**
- * HasStarted checks whether the current Cron ticker has been started.
- */
- hasStarted(): boolean
- }
-}
-
-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.
- *
- * See also the Dir field, which may set PWD in the environment.
- */
- 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.
- *
- * On Unix systems, the value of Dir also determines the
- * child process's PWD environment variable if not otherwise
- * specified. A Unix process represents its working directory
- * not by name but as an implicit reference to a node in the
- * file tree. So, if the child process obtains its working
- * directory by calling a function such as C's getcwd, which
- * computes the canonical name by walking up the file tree, it
- * will not recover the original value of Dir if that value
- * was an alias involving symbolic links. However, if the
- * child process calls Go's [os.Getwd] or GNU C's
- * get_current_dir_name, and the value of PWD is an alias for
- * the current directory, those functions will return the
- * value of PWD, which matches the value of Dir.
- */
- 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 and the returned error is of type
- * [*ExitError], Output populates the Stderr field of the
- * returned error.
- */
- 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
- }
-}
-
-namespace mailer {
- /**
- * Message defines a generic email message struct.
- */
- 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
- }
- /**
- * Mailer defines a base mail client interface.
- */
- interface Mailer {
- [key:string]: any;
- /**
- * Send sends an email with the provided Message.
- */
- send(message: Message): void
- }
-}
-
-namespace subscriptions {
- /**
- * Broker defines a struct for managing subscriptions clients.
- */
- interface Broker {
- }
- interface Broker {
- /**
- * Clients returns a shallow copy of all registered clients indexed
- * with their connection id.
- */
- clients(): _TygojaDict
- }
- interface Broker {
- /**
- * ChunkedClients splits the current clients into a chunked slice.
- */
- chunkedClients(chunkSize: number): Array>
- }
- interface Broker {
- /**
- * TotalClients returns the total number of registered clients.
- */
- totalClients(): number
- }
- interface Broker {
- /**
- * ClientById finds a registered client by its id.
- *
- * Returns non-nil error when client with clientId is not registered.
- */
- clientById(clientId: string): Client
- }
- interface Broker {
- /**
- * Register adds a new client to the broker instance.
- */
- register(client: Client): void
- }
- interface Broker {
- /**
- * Unregister removes a single client by its id and marks it as discarded.
- *
- * If client with clientId doesn't exist, this method does nothing.
- */
- unregister(clientId: string): void
- }
- /**
- * Client is an interface for a generic subscription client.
- */
- interface Client {
- [key:string]: any;
- /**
- * Id Returns the unique id of the client.
- */
- id(): string
- /**
- * Channel returns the client's communication channel.
- *
- * NB! The channel shouldn't be used after calling Discard().
- */
- channel(): undefined
- /**
- * Subscriptions returns a shallow copy of the client subscriptions matching the prefixes.
- * If no prefix is specified, returns all subscriptions.
- */
- subscriptions(...prefixes: string[]): _TygojaDict
- /**
- * Subscribe subscribes the client to the provided subscriptions list.
- *
- * Each subscription can also have "options" (json serialized SubscriptionOptions) as query parameter.
- *
- * Example:
- *
- * ```
- * Subscribe(
- * "subscriptionA",
- * `subscriptionB?options={"query":{"a":1},"headers":{"x_token":"abc"}}`,
- * )
- * ```
- */
- subscribe(...subs: string[]): void
- /**
- * Unsubscribe unsubscribes the client from the provided subscriptions list.
- */
- unsubscribe(...subs: string[]): void
- /**
- * HasSubscription checks if the client is subscribed to `sub`.
- */
- hasSubscription(sub: string): boolean
- /**
- * Set stores any value to the client's context.
- */
- set(key: string, value: any): void
- /**
- * Unset removes a single value from the client's context.
- */
- unset(key: string): void
- /**
- * Get retrieves the key value from the client's context.
- */
- get(key: string): any
- /**
- * Discard marks the client as "discarded" (and closes its channel),
- * meaning that it shouldn't be used anymore for sending new messages.
- *
- * It is safe to call Discard() multiple times.
- */
- discard(): void
- /**
- * IsDiscarded indicates whether the client has been "discarded"
- * and should no longer be used.
- */
- isDiscarded(): boolean
- /**
- * Send sends the specified message to the client's channel (if not discarded).
- */
- send(m: Message): void
- }
- /**
- * Message defines a client's channel data.
- */
- interface Message {
- name: string
- data: string|Array
- }
- interface Message {
- /**
- * WriteSSE writes the current message in a SSE format into the provided writer.
- *
- * For example, writing to a router.Event:
- *
- * ```
- * m := Message{Name: "users/create", Data: []byte{...}}
- * m.WriteSSE(e.Response, "yourEventId")
- * e.Flush()
- * ```
- */
- writeSSE(w: io.Writer, eventId: string): void
- }
-}
-
/**
* Package slog provides structured logging,
* in which log records include a message,
@@ -21719,154 +21884,145 @@ namespace slog {
}
}
-namespace auth {
+namespace subscriptions {
/**
- * Provider defines a common interface for an OAuth2 client.
+ * Broker defines a struct for managing subscriptions clients.
*/
- interface Provider {
+ interface Broker {
+ }
+ interface Broker {
+ /**
+ * Clients returns a shallow copy of all registered clients indexed
+ * with their connection id.
+ */
+ clients(): _TygojaDict
+ }
+ interface Broker {
+ /**
+ * ChunkedClients splits the current clients into a chunked slice.
+ */
+ chunkedClients(chunkSize: number): Array>
+ }
+ interface Broker {
+ /**
+ * TotalClients returns the total number of registered clients.
+ */
+ totalClients(): number
+ }
+ interface Broker {
+ /**
+ * ClientById finds a registered client by its id.
+ *
+ * Returns non-nil error when client with clientId is not registered.
+ */
+ clientById(clientId: string): Client
+ }
+ interface Broker {
+ /**
+ * Register adds a new client to the broker instance.
+ */
+ register(client: Client): void
+ }
+ interface Broker {
+ /**
+ * Unregister removes a single client by its id and marks it as discarded.
+ *
+ * If client with clientId doesn't exist, this method does nothing.
+ */
+ unregister(clientId: string): void
+ }
+ /**
+ * Client is an interface for a generic subscription client.
+ */
+ interface Client {
[key:string]: any;
/**
- * Context returns the context associated with the provider (if any).
+ * Id Returns the unique id of the client.
*/
- context(): context.Context
+ id(): string
/**
- * SetContext assigns the specified context to the current provider.
+ * Channel returns the client's communication channel.
+ *
+ * NB! The channel shouldn't be used after calling Discard().
*/
- setContext(ctx: context.Context): void
+ channel(): undefined
/**
- * PKCE indicates whether the provider can use the PKCE flow.
+ * Subscriptions returns a shallow copy of the client subscriptions matching the prefixes.
+ * If no prefix is specified, returns all subscriptions.
*/
- pkce(): boolean
+ subscriptions(...prefixes: string[]): _TygojaDict
/**
- * SetPKCE toggles the state whether the provider can use the PKCE flow or not.
+ * Subscribe subscribes the client to the provided subscriptions list.
+ *
+ * Each subscription can also have "options" (json serialized SubscriptionOptions) as query parameter.
+ *
+ * Example:
+ *
+ * ```
+ * Subscribe(
+ * "subscriptionA",
+ * `subscriptionB?options={"query":{"a":1},"headers":{"x_token":"abc"}}`,
+ * )
+ * ```
*/
- setPKCE(enable: boolean): void
+ subscribe(...subs: string[]): void
/**
- * DisplayName usually returns provider name as it is officially written
- * and it could be used directly in the UI.
+ * Unsubscribe unsubscribes the client from the provided subscriptions list.
*/
- displayName(): string
+ unsubscribe(...subs: string[]): void
/**
- * SetDisplayName sets the provider's display name.
+ * HasSubscription checks if the client is subscribed to `sub`.
*/
- setDisplayName(displayName: string): void
+ hasSubscription(sub: string): boolean
/**
- * Scopes returns the provider access permissions that will be requested.
+ * Set stores any value to the client's context.
*/
- scopes(): Array
+ set(key: string, value: any): void
/**
- * SetScopes sets the provider access permissions that will be requested later.
+ * Unset removes a single value from the client's context.
*/
- setScopes(scopes: Array): void
+ unset(key: string): void
/**
- * ClientId returns the provider client's app ID.
+ * Get retrieves the key value from the client's context.
*/
- clientId(): string
+ get(key: string): any
/**
- * SetClientId sets the provider client's ID.
+ * Discard marks the client as "discarded" (and closes its channel),
+ * meaning that it shouldn't be used anymore for sending new messages.
+ *
+ * It is safe to call Discard() multiple times.
*/
- setClientId(clientId: string): void
+ discard(): void
/**
- * ClientSecret returns the provider client's app secret.
+ * IsDiscarded indicates whether the client has been "discarded"
+ * and should no longer be used.
*/
- clientSecret(): string
+ isDiscarded(): boolean
/**
- * SetClientSecret sets the provider client's app secret.
+ * Send sends the specified message to the client's channel (if not discarded).
*/
- setClientSecret(secret: string): void
- /**
- * RedirectURL returns the end address to redirect the user
- * going through the OAuth flow.
- */
- redirectURL(): string
- /**
- * SetRedirectURL sets the provider's RedirectURL.
- */
- setRedirectURL(url: string): void
- /**
- * AuthURL returns the provider's authorization service url.
- */
- authURL(): string
- /**
- * SetAuthURL sets the provider's AuthURL.
- */
- setAuthURL(url: string): void
- /**
- * TokenURL returns the provider's token exchange service url.
- */
- tokenURL(): string
- /**
- * SetTokenURL sets the provider's TokenURL.
- */
- setTokenURL(url: string): void
- /**
- * UserInfoURL returns the provider's user info api url.
- */
- userInfoURL(): string
- /**
- * SetUserInfoURL sets the provider's UserInfoURL.
- */
- setUserInfoURL(url: string): void
- /**
- * Extra returns a shallow copy of any custom config data
- * that the provider may need.
- */
- extra(): _TygojaDict
- /**
- * SetExtra updates the provider's custom config data.
- */
- setExtra(data: _TygojaDict): void
- /**
- * Client returns an http client using the provided token.
- */
- client(token: oauth2.Token): (any)
- /**
- * BuildAuthURL returns a URL to the provider's consent page
- * that asks for permissions for the required scopes explicitly.
- */
- buildAuthURL(state: string, ...opts: oauth2.AuthCodeOption[]): string
- /**
- * FetchToken converts an authorization code to token.
- */
- fetchToken(code: string, ...opts: oauth2.AuthCodeOption[]): (oauth2.Token)
- /**
- * FetchRawUserInfo requests and marshalizes into `result` the
- * the OAuth user api response.
- */
- fetchRawUserInfo(token: oauth2.Token): string|Array
- /**
- * FetchAuthUser is similar to FetchRawUserInfo, but normalizes and
- * marshalizes the user api response into a standardized AuthUser struct.
- */
- fetchAuthUser(token: oauth2.Token): (AuthUser)
+ send(m: Message): void
}
/**
- * AuthUser defines a standardized OAuth2 user data structure.
+ * Message defines a client's channel data.
*/
- interface AuthUser {
- expiry: types.DateTime
- rawUser: _TygojaDict
- id: string
+ interface Message {
name: string
- username: string
- email: string
- avatarURL: string
- accessToken: string
- refreshToken: string
- /**
- * @todo
- * deprecated: use AvatarURL instead
- * AvatarUrl will be removed after dropping v0.22 support
- */
- avatarUrl: string
+ data: string|Array
}
- interface AuthUser {
+ interface Message {
/**
- * MarshalJSON implements the [json.Marshaler] interface.
+ * WriteSSE writes the current message in a SSE format into the provided writer.
*
- * @todo remove after dropping v0.22 support
+ * For example, writing to a router.Event:
+ *
+ * ```
+ * m := Message{Name: "users/create", Data: []byte{...}}
+ * m.WriteSSE(e.Response, "yourEventId")
+ * e.Flush()
+ * ```
*/
- marshalJSON(): string|Array
+ writeSSE(w: io.Writer, eventId: string): void
}
}
@@ -21892,612 +22048,6 @@ namespace io {
}
}
-namespace syscall {
- // @ts-ignore
- import errpkg = errors
- /**
- * 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.
- *
- * See RFC 3986. This package generally follows RFC 3986, except where
- * it deviates for compatibility reasons.
- * RFC 6874 followed for IPv6 zone literals.
- */
-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 {
- appendBinary(b: string|Array): 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")
- }
- // @ts-ignore
- import _cgopackage = cgo
-}
-
-namespace jwt {
- /**
- * NumericDate represents a JSON numeric date value, as referenced at
- * https://datatracker.ietf.org/doc/html/rfc7519#section-2.
- */
- type _sIVkVHa = time.Time
- interface NumericDate extends _sIVkVHa {
- }
- 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 hook {
- /**
- * wrapped local Hook embedded struct to limit the public API surface.
- */
- type _sVWAIPu = Hook
- interface mainHook extends _sVWAIPu {
- }
-}
-
-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 bufio {
/**
* Reader implements buffering for an io.Reader object.
@@ -22762,30 +22312,112 @@ namespace bufio {
}
}
-namespace types {
+namespace syscall {
+ // @ts-ignore
+ import errpkg = errors
+ /**
+ * 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 search {
+namespace time {
/**
- * MultiMatchSubquery defines a multi-match record subquery expression.
+ * A Month specifies a month of the year (January = 1, ...).
*/
- interface MultiMatchSubquery {
- targetTableAlias: string
- fromTableName: string
- fromTableAlias: string
- valueIdentifier: string
- joins: Array<(Join | undefined)>
- params: dbx.Params
- }
- interface MultiMatchSubquery {
+ interface Month extends Number{}
+ interface Month {
/**
- * Build converts the expression into a SQL fragment.
- *
- * Implements [dbx.Expression] interface.
+ * String returns the English name of the month ("January", "February", ...).
*/
- build(db: dbx.DB, params: dbx.Params): string
+ string(): string
}
- interface NullFallbackPreference extends Number{}
+ /**
+ * 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")
+ }
+ // @ts-ignore
+ import _cgopackage = cgo
}
/**
@@ -22930,6 +22562,251 @@ namespace multipart {
}
}
+/**
+ * Package url parses URLs and implements query escaping.
+ *
+ * See RFC 3986. This package generally follows RFC 3986, except where
+ * it deviates for compatibility reasons.
+ * RFC 6874 followed for IPv6 zone literals.
+ */
+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 {
+ appendBinary(b: string|Array): 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 http {
/**
* A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
@@ -23345,99 +23222,416 @@ namespace http {
}
}
-/**
- * Package oauth2 provides support for making
- * OAuth2 authorized and authenticated HTTP requests,
- * as specified in RFC 6749.
- * It can additionally grant authorization with Bearer JWT.
- */
-namespace oauth2 {
+namespace store {
+}
+
+namespace types {
+}
+
+namespace sql {
/**
- * An AuthCodeOption is passed to Config.AuthCodeURL.
+ * IsolationLevel is the transaction isolation level used in [TxOptions].
*/
- interface AuthCodeOption {
- [key:string]: any;
+ interface IsolationLevel extends Number{}
+ interface IsolationLevel {
+ /**
+ * String returns the name of the transaction isolation level.
+ */
+ string(): string
}
/**
- * Token represents the credentials used to authorize
- * the requests to access protected resources on the OAuth 2.0
- * provider's backend.
+ * 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.
*
- * Most users of this package should not access fields of Token
- * directly. They're exported mostly for use by related packages
- * implementing derivative OAuth2 flows.
+ * 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 Token {
+ interface Conn {
+ }
+ interface Conn {
/**
- * AccessToken is the token that authorizes and authenticates
- * the requests.
+ * PingContext verifies the connection to the database is still alive.
*/
- accessToken: string
+ pingContext(ctx: context.Context): void
+ }
+ interface Conn {
/**
- * TokenType is the type of token.
- * The Type method returns either this or "Bearer", the default.
+ * ExecContext executes a query without returning any rows.
+ * The args are for any placeholder parameters in the query.
*/
- tokenType: string
+ execContext(ctx: context.Context, query: string, ...args: any[]): Result
+ }
+ interface Conn {
/**
- * RefreshToken is a token that's used by the application
- * (as opposed to the user) to refresh the access token
- * if it expires.
+ * QueryContext executes a query that returns rows, typically a SELECT.
+ * The args are for any placeholder parameters in the query.
*/
- refreshToken: string
+ queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows)
+ }
+ interface Conn {
/**
- * Expiry is the optional expiration time of the access token.
+ * 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.
*
- * If zero, [TokenSource] implementations will reuse the same
- * token forever and RefreshToken or equivalent
- * mechanisms for that TokenSource will not be used.
+ * The provided context is used for the preparation of the statement, not for the
+ * execution of the statement.
*/
- expiry: time.Time
- /**
- * ExpiresIn is the OAuth2 wire format "expires_in" field,
- * which specifies how many seconds later the token expires,
- * relative to an unknown time base approximately around "now".
- * It is the application's responsibility to populate
- * `Expiry` from `ExpiresIn` when required.
- */
- expiresIn: number
+ prepareContext(ctx: context.Context, query: string): (Stmt)
}
- interface Token {
+ interface Conn {
/**
- * Type returns t.TokenType if non-empty, else "Bearer".
- */
- type(): string
- }
- interface Token {
- /**
- * SetAuthHeader sets the Authorization header to r using the access
- * token in t.
+ * Raw executes f exposing the underlying driver connection for the
+ * duration of f. The driverConn must not be used outside of f.
*
- * This method is unnecessary when using [Transport] or an HTTP Client
- * returned by this package.
+ * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable
+ * until [Conn.Close] is called.
*/
- setAuthHeader(r: http.Request): void
+ raw(f: (driverConn: any) => void): void
}
- interface Token {
+ interface Conn {
/**
- * WithExtra returns a new [Token] that's a clone of t, but using the
- * provided raw extra map. This is only intended for use by packages
- * implementing derivative OAuth2 flows.
+ * 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.
*/
- withExtra(extra: any): (Token)
+ beginTx(ctx: context.Context, opts: TxOptions): (Tx)
}
- interface Token {
+ interface Conn {
/**
- * Extra returns an extra field.
- * Extra fields are key-value pairs returned by the server as
- * part of the token retrieval response.
+ * 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.
*/
- extra(key: string): any
+ close(): void
}
- interface Token {
+ /**
+ * ColumnType contains the name and type of a column.
+ */
+ interface ColumnType {
+ }
+ interface ColumnType {
/**
- * Valid reports whether t is non-nil, has an AccessToken, and is not expired.
+ * Name returns the name or alias of the column.
*/
- valid(): boolean
+ 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 jwt {
+ /**
+ * NumericDate represents a JSON numeric date value, as referenced at
+ * https://datatracker.ietf.org/doc/html/rfc7519#section-2.
+ */
+ type _sRxQbal = time.Time
+ interface NumericDate extends _sRxQbal {
+ }
+ 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 hook {
+ /**
+ * wrapped local Hook embedded struct to limit the public API surface.
+ */
+ type _sIvilbe = Hook
+ interface mainHook extends _sIvilbe {
+ }
+}
+
+namespace search {
+ /**
+ * MultiMatchSubquery defines a multi-match record subquery expression.
+ */
+ interface MultiMatchSubquery {
+ targetTableAlias: string
+ fromTableName: string
+ fromTableAlias: string
+ valueIdentifier: string
+ joins: Array<(Join | undefined)>
+ params: dbx.Params
+ }
+ interface MultiMatchSubquery {
+ /**
+ * Build converts the expression into a SQL fragment.
+ *
+ * Implements [dbx.Expression] interface.
+ */
+ build(db: dbx.DB, params: dbx.Params): string
+ }
+ interface NullFallbackPreference extends Number{}
+}
+
+namespace router {
+ // @ts-ignore
+ import validation = ozzo_validation
+ /**
+ * RouterGroup represents a collection of routes and other sub groups
+ * that share common pattern prefix and middlewares.
+ */
+ interface RouterGroup {
+ prefix: string
+ middlewares: Array<(hook.Handler | undefined)>
+ }
+ interface RouterGroup {
+ /**
+ * Group creates and register a new child Group into the current one
+ * with the specified prefix.
+ *
+ * The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]")
+ * and will be concatenated recursively into the final route path, meaning that
+ * only the root level group could have HOST as part of the prefix.
+ *
+ * Returns the newly created group to allow chaining and registering
+ * sub-routes and group specific middlewares.
+ */
+ group(prefix: string): (RouterGroup)
+ }
+ interface RouterGroup {
+ /**
+ * BindFunc registers one or multiple middleware functions to the current group.
+ *
+ * The registered middleware functions are "anonymous" and with default priority,
+ * aka. executes in the order they were registered.
+ *
+ * If you need to specify a named middleware (ex. so that it can be removed)
+ * or middleware with custom exec prirority, use [RouterGroup.Bind] method.
+ */
+ bindFunc(...middlewareFuncs: ((e: T) => void)[]): (RouterGroup)
+ }
+ interface RouterGroup {
+ /**
+ * Bind registers one or multiple middleware handlers to the current group.
+ */
+ bind(...middlewares: (hook.Handler | undefined)[]): (RouterGroup)
+ }
+ interface RouterGroup {
+ /**
+ * Unbind removes one or more middlewares with the specified id(s)
+ * from the current group and its children (if any).
+ *
+ * Anonymous middlewares are not removable, aka. this method does nothing
+ * if the middleware id is an empty string.
+ */
+ unbind(...middlewareIds: string[]): (RouterGroup)
+ }
+ interface RouterGroup {
+ /**
+ * Route registers a single route into the current group.
+ *
+ * Note that the final route path will be the concatenation of all parent groups prefixes + the route path.
+ * The path follows the standard Go net/http ServeMux format ("[HOST]/[PATH]"),
+ * meaning that only a top level group route could have HOST as part of the prefix.
+ *
+ * Returns the newly created route to allow attaching route-only middlewares.
+ */
+ route(method: string, path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * Any is a shorthand for [RouterGroup.AddRoute] with "" as route method (aka. matches any method).
+ */
+ any(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * GET is a shorthand for [RouterGroup.AddRoute] with GET as route method.
+ */
+ get(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * SEARCH is a shorthand for [RouterGroup.AddRoute] with SEARCH as route method.
+ */
+ search(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * POST is a shorthand for [RouterGroup.AddRoute] with POST as route method.
+ */
+ post(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * DELETE is a shorthand for [RouterGroup.AddRoute] with DELETE as route method.
+ */
+ delete(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * PATCH is a shorthand for [RouterGroup.AddRoute] with PATCH as route method.
+ */
+ patch(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * PUT is a shorthand for [RouterGroup.AddRoute] with PUT as route method.
+ */
+ put(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * HEAD is a shorthand for [RouterGroup.AddRoute] with HEAD as route method.
+ */
+ head(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * OPTIONS is a shorthand for [RouterGroup.AddRoute] with OPTIONS as route method.
+ */
+ options(path: string, action: (e: T) => void): (Route)
+ }
+ interface RouterGroup {
+ /**
+ * HasRoute checks whether the specified route pattern (method + path)
+ * is registered in the current group or its children.
+ *
+ * This could be useful to conditionally register and checks for routes
+ * in order prevent panic on duplicated routes.
+ *
+ * Note that routes with anonymous and named wildcard placeholder are treated as equal,
+ * aka. "GET /abc/" is considered the same as "GET /abc/{something...}".
+ */
+ hasRoute(method: string, path: string): boolean
}
}
@@ -23721,137 +23915,99 @@ namespace cron {
}
}
-namespace router {
- // @ts-ignore
- import validation = ozzo_validation
+/**
+ * Package oauth2 provides support for making
+ * OAuth2 authorized and authenticated HTTP requests,
+ * as specified in RFC 6749.
+ * It can additionally grant authorization with Bearer JWT.
+ */
+namespace oauth2 {
/**
- * RouterGroup represents a collection of routes and other sub groups
- * that share common pattern prefix and middlewares.
+ * An AuthCodeOption is passed to Config.AuthCodeURL.
*/
- interface RouterGroup {
- prefix: string
- middlewares: Array<(hook.Handler | undefined)>
+ interface AuthCodeOption {
+ [key:string]: any;
}
- interface RouterGroup {
+ /**
+ * Token represents the credentials used to authorize
+ * the requests to access protected resources on the OAuth 2.0
+ * provider's backend.
+ *
+ * Most users of this package should not access fields of Token
+ * directly. They're exported mostly for use by related packages
+ * implementing derivative OAuth2 flows.
+ */
+ interface Token {
/**
- * Group creates and register a new child Group into the current one
- * with the specified prefix.
+ * AccessToken is the token that authorizes and authenticates
+ * the requests.
+ */
+ accessToken: string
+ /**
+ * TokenType is the type of token.
+ * The Type method returns either this or "Bearer", the default.
+ */
+ tokenType: string
+ /**
+ * RefreshToken is a token that's used by the application
+ * (as opposed to the user) to refresh the access token
+ * if it expires.
+ */
+ refreshToken: string
+ /**
+ * Expiry is the optional expiration time of the access token.
*
- * The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]")
- * and will be concatenated recursively into the final route path, meaning that
- * only the root level group could have HOST as part of the prefix.
+ * If zero, [TokenSource] implementations will reuse the same
+ * token forever and RefreshToken or equivalent
+ * mechanisms for that TokenSource will not be used.
+ */
+ expiry: time.Time
+ /**
+ * ExpiresIn is the OAuth2 wire format "expires_in" field,
+ * which specifies how many seconds later the token expires,
+ * relative to an unknown time base approximately around "now".
+ * It is the application's responsibility to populate
+ * `Expiry` from `ExpiresIn` when required.
+ */
+ expiresIn: number
+ }
+ interface Token {
+ /**
+ * Type returns t.TokenType if non-empty, else "Bearer".
+ */
+ type(): string
+ }
+ interface Token {
+ /**
+ * SetAuthHeader sets the Authorization header to r using the access
+ * token in t.
*
- * Returns the newly created group to allow chaining and registering
- * sub-routes and group specific middlewares.
+ * This method is unnecessary when using [Transport] or an HTTP Client
+ * returned by this package.
*/
- group(prefix: string): (RouterGroup)
+ setAuthHeader(r: http.Request): void
}
- interface RouterGroup {
+ interface Token {
/**
- * BindFunc registers one or multiple middleware functions to the current group.
- *
- * The registered middleware functions are "anonymous" and with default priority,
- * aka. executes in the order they were registered.
- *
- * If you need to specify a named middleware (ex. so that it can be removed)
- * or middleware with custom exec prirority, use [RouterGroup.Bind] method.
+ * WithExtra returns a new [Token] that's a clone of t, but using the
+ * provided raw extra map. This is only intended for use by packages
+ * implementing derivative OAuth2 flows.
*/
- bindFunc(...middlewareFuncs: ((e: T) => void)[]): (RouterGroup)
+ withExtra(extra: any): (Token)
}
- interface RouterGroup {
+ interface Token {
/**
- * Bind registers one or multiple middleware handlers to the current group.
+ * Extra returns an extra field.
+ * Extra fields are key-value pairs returned by the server as
+ * part of the token retrieval response.
*/
- bind(...middlewares: (hook.Handler | undefined)[]): (RouterGroup