mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-05 14:01:43 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
794f1d5a8e | ||
|
|
6d6484c466 | ||
|
|
ded20bd386 | ||
|
|
9afeb0c95e | ||
|
|
30b4184305 | ||
|
|
a6deb6ab90 | ||
|
|
84c2c558da | ||
|
|
ac04d7d66e | ||
|
|
889c5654e3 | ||
|
|
884045d2fe | ||
|
|
aea5de233b | ||
|
|
bcd2ac6f1b | ||
|
|
577d20bf5d | ||
|
|
b2de05e0a4 | ||
|
|
d239adcc0b | ||
|
|
056a0a99bf | ||
|
|
2a387ffc62 | ||
|
|
755502afcd | ||
|
|
21787ba211 | ||
|
|
d1024accc1 | ||
|
|
adc3b0ab1c | ||
|
|
297d085983 | ||
|
|
fb120daaa5 | ||
|
|
529cb8cd6b | ||
|
|
2e4c9db111 | ||
|
|
81ab302068 | ||
|
|
86cc345738 | ||
|
|
37601fe2de | ||
|
|
9014604506 | ||
|
|
cbc7846b96 | ||
|
|
4c5d13fb4f | ||
|
|
ea7320746f | ||
|
|
2ca9b63138 | ||
|
|
3f14a6eab7 | ||
|
|
f99903792a | ||
|
|
7ec7ccc6f0 | ||
|
|
18dcc133f0 | ||
|
|
ae36612c34 | ||
|
|
fbb8fca48e | ||
|
|
0c966ab454 | ||
|
|
eb78f59d31 | ||
|
|
b83f924c7d | ||
|
|
51c083dd58 | ||
|
|
671a6a3aed | ||
|
|
dbb0b6b2d2 | ||
|
|
0d34c00d2e | ||
|
|
8144ad1dda | ||
|
|
9a9b667d4d | ||
|
|
26ef0c697c | ||
|
|
08793ee99f | ||
|
|
75d1c0bc18 | ||
|
|
060a659f83 | ||
|
|
caaac6b145 | ||
|
|
cd14714cf3 | ||
|
|
0b30435183 | ||
|
|
c4b1e2d55e | ||
|
|
58a0b28664 | ||
|
|
2ff2cd874c | ||
|
|
3dd644c15c | ||
|
|
cffbe83399 | ||
|
|
e18ea88113 | ||
|
|
3786e0816d | ||
|
|
cbc88d7a01 | ||
|
|
e92d3cccd0 | ||
|
|
a1d9a9bbc9 |
No files matched your search
@@ -19,9 +19,9 @@ jobs:
|
|||||||
node-version: 20.11.0
|
node-version: 20.11.0
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: '>=1.22.5'
|
go-version: '>=1.26.5'
|
||||||
|
|
||||||
# This step usually is not needed because the /ui/dist is pregenerated locally
|
# This step usually is not needed because the /ui/dist is pregenerated locally
|
||||||
# but its here to ensure that each release embeds the latest admin ui artifacts.
|
# but its here to ensure that each release embeds the latest admin ui artifacts.
|
||||||
|
|||||||
+179
@@ -1,3 +1,182 @@
|
|||||||
|
## v0.22.48
|
||||||
|
|
||||||
|
- (_Backported from v0.39.7_) Replaced `github.com/go-ozzo/ozzo-validation` with the fork `github.com/pocketbase/ozzo-validation` since the original library has recently changed ownership and the new maintainer cannot be trusted.
|
||||||
|
|
||||||
|
- (_Backported from v0.39.7_) Fixed View collection `*` validator and added more friendly error messages ([#7761](https://github.com/pocketbase/pocketbase/issues/7761)).
|
||||||
|
|
||||||
|
- (_Backported from v0.39.7_) ⚠️ Security fix for unhandled panic in internal worker goroutines ([#7762](https://github.com/pocketbase/pocketbase/discussions/7762)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.47
|
||||||
|
|
||||||
|
- (_Backported from v0.39.6_) Bumped the min Go GitHub action version to 1.26.5 as it includes some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.26.5).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.46
|
||||||
|
|
||||||
|
- (_Backported from v0.39.1_) Bumped the min Go GitHub action version to 1.26.4 as it includes some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.26.4).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.45
|
||||||
|
|
||||||
|
- (_Backported from v0.38.2_) Updated all `golang.org/x/` packages to cover the recent [security fixes](https://groups.google.com/g/golang-announce/c/PdiGK3xulk4) _(none of them should be a critical issue in PocketBase but nonetheless it is advised to update)_.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.44
|
||||||
|
|
||||||
|
- (Backported from v0.38.1) Force unset the auth state of existing realtime connections on user tokenKey change.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.43
|
||||||
|
|
||||||
|
- (_Backported from v0.38.0_) Bumped min Go GitHub action version to 1.26.3 because it comes with some [minor bug and security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.26.3).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.42
|
||||||
|
|
||||||
|
- (_Backported from v0.37.4_) Adjusted Bitbucket, GitHub, GitLab and Gitea/Forgejo OAuth2 providers to better reflect recent API updates and doc references.
|
||||||
|
_In case the userinfo data is not sufficient, some of the providers now send a separate list emails request in order to minimize eventual linking security issues caused by custom onpremise setups (e.g. Gitea/Forgejo allows skipping the email verification if an ENV variable is configured)._
|
||||||
|
|
||||||
|
- (_Backported from v0.37.4_) ⚠️ Fixed a pre-hijacking OAuth2 linking vulnerability ([#7662](https://github.com/pocketbase/pocketbase/discussions/7662)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.41
|
||||||
|
|
||||||
|
- (_Backported from v0.36.9_) Updated the Discord `AuthUser.Name` field to use `global_name`.
|
||||||
|
|
||||||
|
- (_Backported from v0.36.9_) Updated `modernc.org/sqlite` to v1.48.2 _(vfs and other error path related fixes)_.
|
||||||
|
|
||||||
|
- (_Backported from v0.36.9_) Bumped min Go GitHub action version to 1.26.2 because it comes with several [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.26.2).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.40
|
||||||
|
|
||||||
|
- (_Backported from v0.36.7_) Updated `modernc.org/sqlite` to v1.46.2 and SQLite 3.51.3.
|
||||||
|
_⚠️ SQLite 3.51.3 fixed a [database corruption bug](https://sqlite.org/wal.html#walresetbug) that is very unlikely to happen (with PocketBase even more so because we queue on app level all writes and explicit transactions through a single db connection), but still it is advised to upgrade._
|
||||||
|
|
||||||
|
- (_Backported from v0.36.7_) Updated other minor Go and npm deps.
|
||||||
|
_The min Go version in the go.mod of the package was also bumped to Go 1.25.0 because some of the newer dep versions require it._
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.39
|
||||||
|
|
||||||
|
- (_Backported from v0.36.6_) Bumped min Go GitHub action version to 1.26.1 because it comes with some [minor bug and security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.26.1).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.38
|
||||||
|
|
||||||
|
- (_Backported from v0.36.0_) Bumped min Go GitHub action version to 1.25.6 because it comes with some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.25.6).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.37
|
||||||
|
|
||||||
|
- (_Backported from v0.34.1_) - Added missing `:` char to the autocomplete regex ([#7353](https://github.com/pocketbase/pocketbase/pull/7353)).
|
||||||
|
|
||||||
|
- (_Backported from v0.34.1_) Bumped min Go GitHub action version to 1.25.5 because it comes with some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.25.5).
|
||||||
|
_The runner action was also updated to `actions/setup-go@v6` since the previous v5 Go source seems [no longer accessible](https://github.com/actions/setup-go/pull/665#issuecomment-3416693714)._
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.36
|
||||||
|
|
||||||
|
- (_Backported from v0.30.2_) Bumped min Go GitHub action version to 1.24.8 since it comes with some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.24.8+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.35
|
||||||
|
|
||||||
|
- (_Backported from v0.29.2_) Bumped min Go GitHub action version to 1.23.12 since it comes with some [minor fixes for the runtime and `database/sql` package](https://github.com/golang/go/issues?q=milestone%3AGo1.23.12+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.34
|
||||||
|
|
||||||
|
- (_Backported from v0.26.6_) Allow OIDC `email_verified` to be int or boolean string since some OIDC providers like AWS Cognito has non-standard userinfo response ([#6657](https://github.com/pocketbase/pocketbase/pull/6657)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.33
|
||||||
|
|
||||||
|
- (_Backported from v0.26.3_) Fixed and normalized logs error serialization across common types for more consistent logs error output ([#6631](https://github.com/pocketbase/pocketbase/issues/6631)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.32
|
||||||
|
|
||||||
|
- (_Backported from v0.26.2_) Updated `golang-jwt/jwt` dependency because it comes with a [minor security fix](https://github.com/golang-jwt/jwt/security/advisories/GHSA-mh63-6h87-95cp).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.31
|
||||||
|
|
||||||
|
- (_Backported from v0.25.5_) Set the current working directory as a default goja script path when executing inline JS strings to allow `require(m)` traversing parent `node_modules` directories.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.30
|
||||||
|
|
||||||
|
- (_Backported from v0.24.4_) Fixed fields extraction for view queries with nested comments ([#6309](https://github.com/pocketbase/pocketbase/discussions/6309)).
|
||||||
|
|
||||||
|
- Bumped GitHub action min Go version to 1.23.5 as it comes with some [minor security fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.23.5).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.29
|
||||||
|
|
||||||
|
- (_Backported from v0.23.11_) Upgraded `golang.org/x/net` to 0.33.0 to fix [CVE-2024-45338](https://www.cve.org/CVERecord?id=CVE-2024-45338).
|
||||||
|
_PocketBase uses the vulnerable functions primarily for the auto html->text mail generation, but most applications shouldn't be affected unless you are manually embedding unrestricted user provided value in your mail templates._
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.28
|
||||||
|
|
||||||
|
- (_Backported from v0.23.10_) Renew the superuser file token cache when clicking on the thumb preview or download link ([#6137](https://github.com/pocketbase/pocketbase/discussions/6137)).
|
||||||
|
|
||||||
|
- (_Backported from v0.23.10_) Upgraded `modernc.org/sqlite` to 1.34.3 to fix "disk io" error on arm64 systems.
|
||||||
|
_If you are extending PocketBase with Go and upgrading with `go get -u` make sure to manually set in your go.mod the `modernc.org/libc` indirect dependency to v1.55.3, aka. the exact same version the driver is using._
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.27
|
||||||
|
|
||||||
|
- Instead of unregistering the realtime client(s), just unset their auth state on delete of their related auth record so that the client(s) can receive the `delete` event ([#5898](https://github.com/pocketbase/pocketbase/issues/5898)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.26
|
||||||
|
|
||||||
|
- (_Backported from v0.23.0-rc_) Added manual WAL checkpoints before creating the zip backup to minimize copying unnecessary data.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.25
|
||||||
|
|
||||||
|
- Refresh the old collections state in the Import UI after successful import submission ([#5861](https://github.com/pocketbase/pocketbase/issues/5861)).
|
||||||
|
|
||||||
|
- Added randomized throttle on failed filter list requests as a very rudimentary measure since some security researches raised concern regarding the possibity of eventual side-channel attacks.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.24
|
||||||
|
|
||||||
|
- Delete new uploaded record files in case of record DB persist error ([#5845](https://github.com/pocketbase/pocketbase/issues/5845)).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.23
|
||||||
|
|
||||||
|
- Updated the hooks watcher to account for the case when hooksDir is a symlink ([#5789](https://github.com/pocketbase/pocketbase/issues/5789)).
|
||||||
|
|
||||||
|
- _(Backported from v0.23.0-rc)_ Registered a default `http.Server.ErrorLog` handler to report general server connection errors as app Debug level logs (e.g. invalid TLS handshakes caused by bots trying to access your server via its IP or other similar errors).
|
||||||
|
|
||||||
|
- Other minor fixes (updated npm dev deps to fix the vulnerabilities warning, added more user friendly realtime topic length error, regenerated JSVM types, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
## v0.22.22
|
||||||
|
|
||||||
|
- Added deprecation log in case Instagram OAuth2 is used (_related to [#5652](https://github.com/pocketbase/pocketbase/discussions/5652)_).
|
||||||
|
|
||||||
|
- Added `update` command warning to prevent unnecessary downloading PocketBase v0.23.0 since it will contain breaking changes.
|
||||||
|
|
||||||
|
- Added global JSVM `toString()` helper (_successor of `readerToString()`_) to stringify any value (bool, number, multi-byte array, io.Reader, etc.).
|
||||||
|
_`readerToString` is still available but it is marked as deprecated. You can also use `toString` as replacement for of `String.fromCharCode` to properly stringify multi-byte unicode characters like emojis._
|
||||||
|
```js
|
||||||
|
decodeURIComponent(escape(String.fromCharCode(...bytes))) -> toString(bytes)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Updated `aws-sdk-go-v2` and removed deprecated `WithEndpointResolverWithOptions`.
|
||||||
|
|
||||||
|
- Backported some of the v0.23.0-rc form validators, fixes and tests.
|
||||||
|
|
||||||
|
- Bumped GitHub action min Go version and dependencies.
|
||||||
|
|
||||||
|
|
||||||
## v0.22.21
|
## v0.22.21
|
||||||
|
|
||||||
- Lock the logs database during backup to prevent `database disk image is malformed` errors in case there is a log write running in the background ([#5541](https://github.com/pocketbase/pocketbase/discussions/5541)).
|
- Lock the logs database during backup to prevent `database disk image is malformed` errors in case there is a log write running in the background ([#5541](https://github.com/pocketbase/pocketbase/discussions/5541)).
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ This document describes how to prepare a PR for a change in the main repository.
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Go 1.21+ (for making changes in the Go code)
|
- Go 1.25+ (for making changes in the Go code)
|
||||||
- Node 18+ (for making changes in the Admin UI)
|
- Node 18+ (for making changes in the Admin UI)
|
||||||
|
|
||||||
If you haven't already, you can fork the main repository and clone your fork so that you can work locally:
|
If you haven't already, you can fork the main repository and clone your fork so that you can work locally:
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ your own custom app specific business logic and still have a single portable exe
|
|||||||
|
|
||||||
Here is a minimal example:
|
Here is a minimal example:
|
||||||
|
|
||||||
0. [Install Go 1.21+](https://go.dev/doc/install) (_if you haven't already_)
|
0. [Install Go 1.25+](https://go.dev/doc/install) (_if you haven't already_)
|
||||||
|
|
||||||
1. Create a new project directory with the following `main.go` file inside it:
|
1. Create a new project directory with the following `main.go` file inside it:
|
||||||
```go
|
```go
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/tools/inflector"
|
"github.com/pocketbase/pocketbase/tools/inflector"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
"github.com/pocketbase/pocketbase/tools/rest"
|
"github.com/pocketbase/pocketbase/tools/rest"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
@@ -172,7 +173,7 @@ func (api *backupApi) restore(c echo.Context) error {
|
|||||||
return NewBadRequestError("Missing or invalid backup file.", err)
|
return NewBadRequestError("Missing or invalid backup file.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
// wait max 15 minutes to fetch the backup
|
// wait max 15 minutes to fetch the backup
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -183,7 +184,7 @@ func (api *backupApi) restore(c echo.Context) error {
|
|||||||
if err := api.app.RestoreBackup(ctx, key); err != nil {
|
if err := api.app.RestoreBackup(ctx, key); err != nil {
|
||||||
api.app.Logger().Error("Failed to restore backup", "key", key, "error", err.Error())
|
api.app.Logger().Error("Failed to restore backup", "key", key, "error", err.Error())
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
return c.NoContent(http.StatusNoContent)
|
return c.NoContent(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -231,9 +231,14 @@ func (api *realtimeApi) updateClientsAuthModel(contextKey string, newModel model
|
|||||||
if clientModel != nil &&
|
if clientModel != nil &&
|
||||||
clientModel.TableName() == newModel.TableName() &&
|
clientModel.TableName() == newModel.TableName() &&
|
||||||
clientModel.GetId() == newModel.GetId() {
|
clientModel.GetId() == newModel.GetId() {
|
||||||
|
record, ok := newModel.(*models.Record)
|
||||||
|
if ok && record.OriginalCopy().TokenKey() != record.TokenKey() {
|
||||||
|
client.Unset(contextKey)
|
||||||
|
} else {
|
||||||
client.Set(contextKey, newModel)
|
client.Set(contextKey, newModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -245,7 +250,7 @@ func (api *realtimeApi) unregisterClientsByAuthModel(contextKey string, model mo
|
|||||||
if clientModel != nil &&
|
if clientModel != nil &&
|
||||||
clientModel.TableName() == model.TableName() &&
|
clientModel.TableName() == model.TableName() &&
|
||||||
clientModel.GetId() == model.GetId() {
|
clientModel.GetId() == model.GetId() {
|
||||||
api.app.SubscriptionsBroker().Unregister(client.Id())
|
client.Unset(contextKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+131
-21
@@ -249,22 +249,48 @@ func TestRealtimeAuthRecordDeleteEvent(t *testing.T) {
|
|||||||
|
|
||||||
apis.InitApi(testApp)
|
apis.InitApi(testApp)
|
||||||
|
|
||||||
authRecord, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
authRecord1, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := subscriptions.NewDefaultClient()
|
authRecord2, err := testApp.Dao().FindFirstRecordByData("users", "email", "test2@example.com")
|
||||||
client.Set(apis.ContextAuthRecordKey, authRecord)
|
if err != nil {
|
||||||
testApp.SubscriptionsBroker().Register(client)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client1 := subscriptions.NewDefaultClient()
|
||||||
|
client1.Set(apis.ContextAuthRecordKey, authRecord1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client1)
|
||||||
|
|
||||||
|
client2 := subscriptions.NewDefaultClient()
|
||||||
|
client2.Set(apis.ContextAuthRecordKey, authRecord1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client2)
|
||||||
|
|
||||||
|
client3 := subscriptions.NewDefaultClient()
|
||||||
|
client3.Set(apis.ContextAuthRecordKey, authRecord2)
|
||||||
|
testApp.SubscriptionsBroker().Register(client3)
|
||||||
|
|
||||||
|
// "delete" authRecord1
|
||||||
e := new(core.ModelEvent)
|
e := new(core.ModelEvent)
|
||||||
e.Dao = testApp.Dao()
|
e.Dao = testApp.Dao()
|
||||||
e.Model = authRecord
|
e.Model = authRecord1
|
||||||
testApp.OnModelAfterDelete().Trigger(e)
|
testApp.OnModelAfterDelete().Trigger(e)
|
||||||
|
|
||||||
if len(testApp.SubscriptionsBroker().Clients()) != 0 {
|
if total := len(testApp.SubscriptionsBroker().Clients()); total != 3 {
|
||||||
t.Fatalf("Expected no subscription clients, found %d", len(testApp.SubscriptionsBroker().Clients()))
|
t.Fatalf("Expected %d subscription clients, found %d", 3, total)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client1.Get(apis.ContextAuthRecordKey); auth != nil {
|
||||||
|
t.Fatalf("[client1] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client2.Get(apis.ContextAuthRecordKey); auth != nil {
|
||||||
|
t.Fatalf("[client2] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client3.Get(apis.ContextAuthRecordKey); auth == nil || auth.(*models.Record).Id != authRecord2.Id {
|
||||||
|
t.Fatalf("[client3] Expected the auth state to be left unchanged, found %#v", auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,28 +327,87 @@ func TestRealtimeAuthRecordUpdateEvent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRealtimeAuthRecordUnsetOnTokenKeyRefresh(t *testing.T) {
|
||||||
|
testApp, _ := tests.NewTestApp()
|
||||||
|
defer testApp.Cleanup()
|
||||||
|
|
||||||
|
apis.InitApi(testApp)
|
||||||
|
|
||||||
|
authRecord1, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := subscriptions.NewDefaultClient()
|
||||||
|
client.Set(apis.ContextAuthRecordKey, authRecord1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client)
|
||||||
|
|
||||||
|
// refetch the authRecord and refresh its tokenKey
|
||||||
|
authRecord2, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
authRecord2.RefreshTokenKey()
|
||||||
|
|
||||||
|
e := new(core.ModelEvent)
|
||||||
|
e.Dao = testApp.Dao()
|
||||||
|
e.Model = authRecord2
|
||||||
|
testApp.OnModelAfterUpdate().Trigger(e)
|
||||||
|
|
||||||
|
clientAuthRecord, _ := client.Get(apis.ContextAuthRecordKey).(*models.Record)
|
||||||
|
if clientAuthRecord != nil {
|
||||||
|
t.Fatalf("Expected authRecord to be unset, got %q", clientAuthRecord.Email())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRealtimeAdminDeleteEvent(t *testing.T) {
|
func TestRealtimeAdminDeleteEvent(t *testing.T) {
|
||||||
testApp, _ := tests.NewTestApp()
|
testApp, _ := tests.NewTestApp()
|
||||||
defer testApp.Cleanup()
|
defer testApp.Cleanup()
|
||||||
|
|
||||||
apis.InitApi(testApp)
|
apis.InitApi(testApp)
|
||||||
|
|
||||||
admin, err := testApp.Dao().FindAdminByEmail("test@example.com")
|
admin1, err := testApp.Dao().FindAdminByEmail("test@example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := subscriptions.NewDefaultClient()
|
admin2, err := testApp.Dao().FindAdminByEmail("test2@example.com")
|
||||||
client.Set(apis.ContextAdminKey, admin)
|
if err != nil {
|
||||||
testApp.SubscriptionsBroker().Register(client)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client1 := subscriptions.NewDefaultClient()
|
||||||
|
client1.Set(apis.ContextAdminKey, admin1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client1)
|
||||||
|
|
||||||
|
client2 := subscriptions.NewDefaultClient()
|
||||||
|
client2.Set(apis.ContextAdminKey, admin1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client2)
|
||||||
|
|
||||||
|
client3 := subscriptions.NewDefaultClient()
|
||||||
|
client3.Set(apis.ContextAdminKey, admin2)
|
||||||
|
testApp.SubscriptionsBroker().Register(client3)
|
||||||
|
|
||||||
|
// "delete" admin1
|
||||||
e := new(core.ModelEvent)
|
e := new(core.ModelEvent)
|
||||||
e.Dao = testApp.Dao()
|
e.Dao = testApp.Dao()
|
||||||
e.Model = admin
|
e.Model = admin1
|
||||||
testApp.OnModelAfterDelete().Trigger(e)
|
testApp.OnModelAfterDelete().Trigger(e)
|
||||||
|
|
||||||
if len(testApp.SubscriptionsBroker().Clients()) != 0 {
|
if total := len(testApp.SubscriptionsBroker().Clients()); total != 3 {
|
||||||
t.Fatalf("Expected no subscription clients, found %d", len(testApp.SubscriptionsBroker().Clients()))
|
t.Fatalf("Expected %d subscription clients, found %d", 3, total)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client1.Get(apis.ContextAdminKey); auth != nil {
|
||||||
|
t.Fatalf("[client1] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client2.Get(apis.ContextAdminKey); auth != nil {
|
||||||
|
t.Fatalf("[client2] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client3.Get(apis.ContextAdminKey); auth == nil || auth.(*models.Admin).Id != admin2.Id {
|
||||||
|
t.Fatalf("[client3] Expected the auth state to be left unchanged, found %#v", auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,16 +479,29 @@ func TestRealtimeCustomAuthModelDeleteEvent(t *testing.T) {
|
|||||||
|
|
||||||
apis.InitApi(testApp)
|
apis.InitApi(testApp)
|
||||||
|
|
||||||
authRecord, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
authRecord1, err := testApp.Dao().FindFirstRecordByData("users", "email", "test@example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := subscriptions.NewDefaultClient()
|
authRecord2, err := testApp.Dao().FindFirstRecordByData("users", "email", "test2@example.com")
|
||||||
client.Set(apis.ContextAuthRecordKey, authRecord)
|
if err != nil {
|
||||||
testApp.SubscriptionsBroker().Register(client)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// refetch the authRecord as CustomUser
|
client1 := subscriptions.NewDefaultClient()
|
||||||
|
client1.Set(apis.ContextAuthRecordKey, authRecord1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client1)
|
||||||
|
|
||||||
|
client2 := subscriptions.NewDefaultClient()
|
||||||
|
client2.Set(apis.ContextAuthRecordKey, authRecord1)
|
||||||
|
testApp.SubscriptionsBroker().Register(client2)
|
||||||
|
|
||||||
|
client3 := subscriptions.NewDefaultClient()
|
||||||
|
client3.Set(apis.ContextAuthRecordKey, authRecord2)
|
||||||
|
testApp.SubscriptionsBroker().Register(client3)
|
||||||
|
|
||||||
|
// refetch authRecord1 as CustomUser
|
||||||
customUser, err := findCustomUserByEmail(testApp.Dao(), "test@example.com")
|
customUser, err := findCustomUserByEmail(testApp.Dao(), "test@example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -414,8 +512,20 @@ func TestRealtimeCustomAuthModelDeleteEvent(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(testApp.SubscriptionsBroker().Clients()) != 0 {
|
if total := len(testApp.SubscriptionsBroker().Clients()); total != 3 {
|
||||||
t.Fatalf("Expected no subscription clients, found %d", len(testApp.SubscriptionsBroker().Clients()))
|
t.Fatalf("Expected %d subscription clients, found %d", 3, total)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client1.Get(apis.ContextAuthRecordKey); auth != nil {
|
||||||
|
t.Fatalf("[client1] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client2.Get(apis.ContextAuthRecordKey); auth != nil {
|
||||||
|
t.Fatalf("[client2] Expected the auth state to be unset, found %#v", auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth := client3.Get(apis.ContextAuthRecordKey); auth == nil || auth.(*models.Record).Id != authRecord2.Id {
|
||||||
|
t.Fatalf("[client3] Expected the auth state to be left unchanged, found %#v", auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -663,10 +663,13 @@ func TestRecordAuthConfirmPasswordReset(t *testing.T) {
|
|||||||
}`),
|
}`),
|
||||||
ExpectedStatus: 204,
|
ExpectedStatus: 204,
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"OnModelAfterUpdate": 1,
|
|
||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
|
"OnModelAfterUpdate": 1,
|
||||||
"OnRecordBeforeConfirmPasswordResetRequest": 1,
|
"OnRecordBeforeConfirmPasswordResetRequest": 1,
|
||||||
"OnRecordAfterConfirmPasswordResetRequest": 1,
|
"OnRecordAfterConfirmPasswordResetRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
user, err := app.Dao().FindAuthRecordByEmail("users", "test@example.com")
|
user, err := app.Dao().FindAuthRecordByEmail("users", "test@example.com")
|
||||||
@@ -770,10 +773,18 @@ func TestRecordAuthConfirmPasswordReset(t *testing.T) {
|
|||||||
t.Fatalf("Failed to fetch confirm password user: %v", err)
|
t.Fatalf("Failed to fetch confirm password user: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldTokenKey := user.TokenKey()
|
||||||
|
|
||||||
// ensure that the user is already verified
|
// ensure that the user is already verified
|
||||||
user.SetVerified(true)
|
user.SetVerified(true)
|
||||||
if err := app.Dao().WithoutHooks().SaveRecord(user); err != nil {
|
if err := app.Dao().WithoutHooks().SaveRecord(user); err != nil {
|
||||||
t.Fatalf("Failed to update user verified state")
|
t.Fatal("Failed to update user verified state")
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore original token key that was reseted after the verified change
|
||||||
|
user.SetTokenKey(oldTokenKey)
|
||||||
|
if err := app.Dao().WithoutHooks().SaveRecord(user); err != nil {
|
||||||
|
t.Fatal("Failed to reset user tokenKey")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AfterTestFunc: func(t *testing.T, app *tests.TestApp, res *http.Response) {
|
AfterTestFunc: func(t *testing.T, app *tests.TestApp, res *http.Response) {
|
||||||
@@ -812,10 +823,13 @@ func TestRecordAuthConfirmPasswordReset(t *testing.T) {
|
|||||||
ExpectedStatus: 400,
|
ExpectedStatus: 400,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"OnModelAfterUpdate": 1,
|
|
||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
|
"OnModelAfterUpdate": 1,
|
||||||
"OnRecordBeforeConfirmPasswordResetRequest": 1,
|
"OnRecordBeforeConfirmPasswordResetRequest": 1,
|
||||||
"OnRecordAfterConfirmPasswordResetRequest": 1,
|
"OnRecordAfterConfirmPasswordResetRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -987,10 +1001,13 @@ func TestRecordAuthConfirmVerification(t *testing.T) {
|
|||||||
}`),
|
}`),
|
||||||
ExpectedStatus: 204,
|
ExpectedStatus: 204,
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"OnModelAfterUpdate": 1,
|
|
||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
|
"OnModelAfterUpdate": 1,
|
||||||
"OnRecordBeforeConfirmVerificationRequest": 1,
|
"OnRecordBeforeConfirmVerificationRequest": 1,
|
||||||
"OnRecordAfterConfirmVerificationRequest": 1,
|
"OnRecordAfterConfirmVerificationRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1037,10 +1054,13 @@ func TestRecordAuthConfirmVerification(t *testing.T) {
|
|||||||
ExpectedStatus: 400,
|
ExpectedStatus: 400,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"OnModelAfterUpdate": 1,
|
|
||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
|
"OnModelAfterUpdate": 1,
|
||||||
"OnRecordBeforeConfirmVerificationRequest": 1,
|
"OnRecordBeforeConfirmVerificationRequest": 1,
|
||||||
"OnRecordAfterConfirmVerificationRequest": 1,
|
"OnRecordAfterConfirmVerificationRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1227,10 +1247,13 @@ func TestRecordAuthConfirmEmailChange(t *testing.T) {
|
|||||||
}`),
|
}`),
|
||||||
ExpectedStatus: 204,
|
ExpectedStatus: 204,
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"OnModelAfterUpdate": 1,
|
|
||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
|
"OnModelAfterUpdate": 1,
|
||||||
"OnRecordBeforeConfirmEmailChangeRequest": 1,
|
"OnRecordBeforeConfirmEmailChangeRequest": 1,
|
||||||
"OnRecordAfterConfirmEmailChangeRequest": 1,
|
"OnRecordAfterConfirmEmailChangeRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1267,6 +1290,9 @@ func TestRecordAuthConfirmEmailChange(t *testing.T) {
|
|||||||
"OnModelBeforeUpdate": 1,
|
"OnModelBeforeUpdate": 1,
|
||||||
"OnRecordBeforeConfirmEmailChangeRequest": 1,
|
"OnRecordBeforeConfirmEmailChangeRequest": 1,
|
||||||
"OnRecordAfterConfirmEmailChangeRequest": 1,
|
"OnRecordAfterConfirmEmailChangeRequest": 1,
|
||||||
|
// external auths deletion
|
||||||
|
"OnModelBeforeDelete": 2,
|
||||||
|
"OnModelAfterDelete": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-1
@@ -1,9 +1,12 @@
|
|||||||
package apis
|
package apis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
@@ -71,7 +74,13 @@ func (api *recordApi) list(c echo.Context) error {
|
|||||||
|
|
||||||
records := []*models.Record{}
|
records := []*models.Record{}
|
||||||
|
|
||||||
result, err := searchProvider.ParseAndExec(c.QueryParams().Encode(), &records)
|
// note: in v0.23.0 this has been migrated as option check in the search.Provider
|
||||||
|
queryStr := c.QueryParams().Encode()
|
||||||
|
if len(queryStr) > 2048 {
|
||||||
|
return NewBadRequestError("query string is too large", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := searchProvider.ParseAndExec(queryStr, &records)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewBadRequestError("", err)
|
return NewBadRequestError("", err)
|
||||||
}
|
}
|
||||||
@@ -91,10 +100,43 @@ func (api *recordApi) list(c echo.Context) error {
|
|||||||
api.app.Logger().Debug("Failed to enrich list records", slog.String("error", err.Error()))
|
api.app.Logger().Debug("Failed to enrich list records", slog.String("error", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// note: in v0.23.0 this is combined with extra check for repeated attempts
|
||||||
|
//
|
||||||
|
// Add a randomized throttle in case of empty search filter attempts.
|
||||||
|
//
|
||||||
|
// This is just for extra precaution since security researches raised concern regarding the possibity of eventual
|
||||||
|
// timing attacks because the List API rule acts also as filter and executes in a single run with the client-side filters.
|
||||||
|
// This is by design and it is an accepted tradeoff between performance, usability and correctness.
|
||||||
|
//
|
||||||
|
// While technically the below doesn't fully guarantee protection against filter timing attacks, in practice combined with the network latency it makes them even less feasible.
|
||||||
|
// A properly configured rate limiter or individual fields Hidden checks are better suited if you are really concerned about eventual information disclosure by side-channel attacks.
|
||||||
|
//
|
||||||
|
// In all cases it doesn't really matter that much because it doesn't affect the builtin PocketBase security sensitive fields (e.g. password and tokenKey) since they
|
||||||
|
// are not client-side filterable and in the few places where they need to be compared against an external value, a constant time check is used.
|
||||||
|
if requestInfo.Admin == nil &&
|
||||||
|
(collection.ListRule != nil && *collection.ListRule != "") &&
|
||||||
|
(requestInfo.Query["filter"] != "") &&
|
||||||
|
len(e.Records) == 0 {
|
||||||
|
api.app.Logger().Debug("Randomized throttle because of failed filter search", "collectionId", collection.Id)
|
||||||
|
randomizedThrottle(100)
|
||||||
|
}
|
||||||
|
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomizedThrottle(softMax int64) {
|
||||||
|
var timeout int64
|
||||||
|
randRange, err := cryptoRand.Int(cryptoRand.Reader, big.NewInt(softMax))
|
||||||
|
if err == nil {
|
||||||
|
timeout = randRange.Int64()
|
||||||
|
} else {
|
||||||
|
timeout = softMax
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Duration(timeout) * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
func (api *recordApi) view(c echo.Context) error {
|
func (api *recordApi) view(c echo.Context) error {
|
||||||
collection, _ := c.Get(ContextCollectionKey).(*models.Collection)
|
collection, _ := c.Get(ContextCollectionKey).(*models.Collection)
|
||||||
if collection == nil {
|
if collection == nil {
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ func Serve(app core.App, config ServeConfig) (*http.Server, error) {
|
|||||||
BaseContext: func(l net.Listener) context.Context {
|
BaseContext: func(l net.Listener) context.Context {
|
||||||
return baseCtx
|
return baseCtx
|
||||||
},
|
},
|
||||||
|
ErrorLog: log.New(&serverErrorLogWriter{app: app}, "", 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
serveEvent := &core.ServeEvent{
|
serveEvent := &core.ServeEvent{
|
||||||
@@ -275,3 +276,13 @@ func runMigrations(app core.App) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type serverErrorLogWriter struct {
|
||||||
|
app core.App
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serverErrorLogWriter) Write(p []byte) (int, error) {
|
||||||
|
s.app.Logger().Debug(strings.TrimSpace(string(p)))
|
||||||
|
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
+1
-1
@@ -3,8 +3,8 @@ package apis
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models/settings"
|
"github.com/pocketbase/pocketbase/models/settings"
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|||||||
+2
-2
@@ -1278,7 +1278,7 @@ func (app *BaseApp) initLogger() error {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -1289,7 +1289,7 @@ func (app *BaseApp) initLogger() error {
|
|||||||
handler.WriteAll(ctx)
|
handler.WriteAll(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
app.logger = slog.New(handler)
|
app.logger = slog.New(handler)
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -74,7 +74,11 @@ func (app *BaseApp) CreateBackup(ctx context.Context, name string) error {
|
|||||||
tempPath := filepath.Join(localTempDir, "pb_backup_"+security.PseudorandomString(4))
|
tempPath := filepath.Join(localTempDir, "pb_backup_"+security.PseudorandomString(4))
|
||||||
createErr := app.Dao().RunInTransaction(func(dataTXDao *daos.Dao) error {
|
createErr := app.Dao().RunInTransaction(func(dataTXDao *daos.Dao) error {
|
||||||
return app.LogsDao().RunInTransaction(func(logsTXDao *daos.Dao) error {
|
return app.LogsDao().RunInTransaction(func(logsTXDao *daos.Dao) error {
|
||||||
// @todo consider experimenting with temp switching the readonly pragma after the db interface change
|
// run manual checkpoint and truncate the WAL files
|
||||||
|
// (errors are ignored because it is not that important and the PRAGMA may not be supported by the used driver)
|
||||||
|
dataTXDao.DB().NewQuery("PRAGMA wal_checkpoint(TRUNCATE)").Execute()
|
||||||
|
logsTXDao.DB().NewQuery("PRAGMA wal_checkpoint(TRUNCATE)").Execute()
|
||||||
|
|
||||||
return archive.Create(app.DataDir(), tempPath, exclude...)
|
return archive.Create(app.DataDir(), tempPath, exclude...)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -584,6 +584,8 @@ func (dao *Dao) CanAccessRecord(record *models.Record, requestInfo *models.Reque
|
|||||||
// If record.IsNew() is true, the method will perform a create, otherwise an update.
|
// If record.IsNew() is true, the method will perform a create, otherwise an update.
|
||||||
// To explicitly mark a record for update you can use record.MarkAsNotNew().
|
// To explicitly mark a record for update you can use record.MarkAsNotNew().
|
||||||
func (dao *Dao) SaveRecord(record *models.Record) error {
|
func (dao *Dao) SaveRecord(record *models.Record) error {
|
||||||
|
var needToDeleteExternalAuths bool
|
||||||
|
|
||||||
if record.Collection().IsAuth() {
|
if record.Collection().IsAuth() {
|
||||||
if record.Username() == "" {
|
if record.Username() == "" {
|
||||||
return errors.New("unable to save auth record without username")
|
return errors.New("unable to save auth record without username")
|
||||||
@@ -604,11 +606,46 @@ func (dao *Dao) SaveRecord(record *models.Record) error {
|
|||||||
return errors.New("the auth record ID must be unique across all auth collections")
|
return errors.New("the auth record ID must be unique across all auth collections")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !record.IsNew() && record.Verified() {
|
||||||
|
lastSavedRecord, err := dao.FindRecordById(record.Collection().Id, record.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case upgrading from "unverified" -> "verified" mark all pre-existing OAuth2 links
|
||||||
|
// for deletion since there is no reliable way to verify that they weren't created by an attacker
|
||||||
|
if !lastSavedRecord.Verified() && record.Verified() {
|
||||||
|
needToDeleteExternalAuths = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !needToDeleteExternalAuths {
|
||||||
return dao.Save(record)
|
return dao.Save(record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dao.RunInTransaction(func(txDao *Dao) error {
|
||||||
|
externalAuths, err := txDao.FindAllExternalAuthsByRecord(record)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(externalAuths) > 0 {
|
||||||
|
// delete all pre-existing external auths
|
||||||
|
for _, ea := range externalAuths {
|
||||||
|
if err := txDao.DeleteExternalAuth(ea); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// force refresh tokens reset (if not already)
|
||||||
|
record.RefreshTokenKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
return txDao.Save(record)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteRecord deletes the provided Record model.
|
// DeleteRecord deletes the provided Record model.
|
||||||
//
|
//
|
||||||
// This method will also cascade the delete operation to all linked
|
// This method will also cascade the delete operation to all linked
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
"github.com/pocketbase/pocketbase/tools/dbutils"
|
"github.com/pocketbase/pocketbase/tools/dbutils"
|
||||||
|
|||||||
+10
-8
@@ -260,6 +260,12 @@ func (dao *Dao) parseQueryToFields(selectQuery string) (map[string]*queryField,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, col := range p.columns {
|
for _, col := range p.columns {
|
||||||
|
// note: it should be safe to use the already parsed alias as there
|
||||||
|
// is no valid SQL where * column can be aliased to something else
|
||||||
|
if col.alias == "*" {
|
||||||
|
return nil, errors.New("wildcard columns (*) are not supported - manually type the collection field names you want the view query to have")
|
||||||
|
}
|
||||||
|
|
||||||
colLower := strings.ToLower(col.original)
|
colLower := strings.ToLower(col.original)
|
||||||
|
|
||||||
// numeric aggregations
|
// numeric aggregations
|
||||||
@@ -326,10 +332,6 @@ func (dao *Dao) parseQueryToFields(selectQuery string) (map[string]*queryField,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if fieldName == "*" {
|
|
||||||
return nil, errors.New("dynamic column names are not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the first field by name (case insensitive)
|
// find the first field by name (case insensitive)
|
||||||
var field *schema.SchemaField
|
var field *schema.SchemaField
|
||||||
for _, f := range collection.Schema.Fields() {
|
for _, f := range collection.Schema.Fields() {
|
||||||
@@ -462,9 +464,9 @@ type identifiersParser struct {
|
|||||||
|
|
||||||
func (p *identifiersParser) parse(selectQuery string) error {
|
func (p *identifiersParser) parse(selectQuery string) error {
|
||||||
str := strings.Trim(strings.TrimSpace(selectQuery), ";")
|
str := strings.Trim(strings.TrimSpace(selectQuery), ";")
|
||||||
str = joinReplaceRegex.ReplaceAllString(str, " _join_ ")
|
|
||||||
str = discardReplaceRegex.ReplaceAllString(str, " _discard_ ")
|
|
||||||
str = commentsReplaceRegex.ReplaceAllString(str, "")
|
str = commentsReplaceRegex.ReplaceAllString(str, "")
|
||||||
|
str = joinReplaceRegex.ReplaceAllString(str, " __pb_join__ ")
|
||||||
|
str = discardReplaceRegex.ReplaceAllString(str, " __pb_discard__ ")
|
||||||
|
|
||||||
tk := tokenizer.NewFromString(str)
|
tk := tokenizer.NewFromString(str)
|
||||||
tk.Separators(',', ' ', '\n', '\t')
|
tk.Separators(',', ' ', '\n', '\t')
|
||||||
@@ -499,7 +501,7 @@ func (p *identifiersParser) parse(selectQuery string) error {
|
|||||||
skip = false
|
skip = false
|
||||||
partType = "from"
|
partType = "from"
|
||||||
activeBuilder = &fromParts
|
activeBuilder = &fromParts
|
||||||
case "_join_":
|
case "__pb_join__":
|
||||||
skip = false
|
skip = false
|
||||||
|
|
||||||
// the previous part was also a join
|
// the previous part was also a join
|
||||||
@@ -509,7 +511,7 @@ func (p *identifiersParser) parse(selectQuery string) error {
|
|||||||
|
|
||||||
partType = "join"
|
partType = "join"
|
||||||
activeBuilder = &joinParts
|
activeBuilder = &joinParts
|
||||||
case "_discard_":
|
case "__pb_discard__":
|
||||||
// skip following tokens
|
// skip following tokens
|
||||||
skip = true
|
skip = true
|
||||||
default:
|
default:
|
||||||
|
|||||||
+19
-3
@@ -243,16 +243,32 @@ func TestCreateViewSchema(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"wrapped query with wildcard column",
|
||||||
|
"select * from (select 1 as id)",
|
||||||
|
true,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"query with comments",
|
"query with comments",
|
||||||
`
|
`
|
||||||
select
|
select
|
||||||
-- test single line
|
-- test single line
|
||||||
id,
|
demo1.id,
|
||||||
text,
|
demo1.text,
|
||||||
/* multi
|
/* multi
|
||||||
line comment */
|
line comment */
|
||||||
url, created, updated from demo1
|
demo1.url, demo1.created, demo2.updated from demo1
|
||||||
|
-- comment before join
|
||||||
|
join demo2 ON (
|
||||||
|
-- comment inside join
|
||||||
|
demo2.id = demo1.id
|
||||||
|
)
|
||||||
|
-- comment before where
|
||||||
|
where (
|
||||||
|
-- comment inside where
|
||||||
|
demo2.id = demo1.id
|
||||||
|
)
|
||||||
`,
|
`,
|
||||||
false,
|
false,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/mails"
|
"github.com/pocketbase/pocketbase/mails"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package forms
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RealtimeSubscribe is a realtime subscriptions request form.
|
// RealtimeSubscribe is a realtime subscriptions request form.
|
||||||
@@ -19,5 +19,9 @@ func NewRealtimeSubscribe() *RealtimeSubscribe {
|
|||||||
func (form *RealtimeSubscribe) Validate() error {
|
func (form *RealtimeSubscribe) Validate() error {
|
||||||
return validation.ValidateStruct(form,
|
return validation.ValidateStruct(form,
|
||||||
validation.Field(&form.ClientId, validation.Required, validation.Length(1, 255)),
|
validation.Field(&form.ClientId, validation.Required, validation.Length(1, 255)),
|
||||||
|
validation.Field(&form.Subscriptions,
|
||||||
|
validation.Length(0, 1000),
|
||||||
|
validation.Each(validation.Length(0, 2500)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,96 @@
|
|||||||
package forms_test
|
package forms_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRealtimeSubscribeValidate(t *testing.T) {
|
func TestRealtimeSubscribeValidate(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
validSubscriptionsLimit := make([]string, 1000)
|
||||||
|
for i := 0; i < len(validSubscriptionsLimit); i++ {
|
||||||
|
validSubscriptionsLimit[i] = fmt.Sprintf(`"%d"`, i)
|
||||||
|
}
|
||||||
|
invalidSubscriptionsLimit := make([]string, 1001)
|
||||||
|
for i := 0; i < len(invalidSubscriptionsLimit); i++ {
|
||||||
|
invalidSubscriptionsLimit[i] = fmt.Sprintf(`"%d"`, i)
|
||||||
|
}
|
||||||
|
|
||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
clientId string
|
name string
|
||||||
expectError bool
|
data string
|
||||||
|
expectedErrors []string
|
||||||
}{
|
}{
|
||||||
{"", true},
|
{
|
||||||
{strings.Repeat("a", 256), true},
|
"empty data",
|
||||||
{"test", false},
|
`{}`,
|
||||||
|
[]string{"clientId"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientId > max chars limit",
|
||||||
|
`{"clientId":"` + strings.Repeat("a", 256) + `"}`,
|
||||||
|
[]string{"clientId"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientId <= max chars limit",
|
||||||
|
`{"clientId":"` + strings.Repeat("a", 255) + `"}`,
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"total subscriptions > max limit",
|
||||||
|
`{"clientId":"test", "subscriptions":[` + strings.Join(invalidSubscriptionsLimit, ",") + `]}`,
|
||||||
|
[]string{"subscriptions"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"total subscriptions <= max limit",
|
||||||
|
`{"clientId":"test", "subscriptions":[` + strings.Join(validSubscriptionsLimit, ",") + `]}`,
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"single subscription > max limit",
|
||||||
|
`{"clientId":"test", "subscriptions":["abc", "` + strings.Repeat("a", 2501) + `"]}`,
|
||||||
|
[]string{"subscriptions"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"single subscription <= max limit",
|
||||||
|
`{"clientId":"test", "subscriptions":["abc", "` + strings.Repeat("a", 2500) + `"]}`,
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
|
t.Run(s.name, func(t *testing.T) {
|
||||||
form := forms.NewRealtimeSubscribe()
|
form := forms.NewRealtimeSubscribe()
|
||||||
form.ClientId = s.clientId
|
|
||||||
|
|
||||||
err := form.Validate()
|
err := json.Unmarshal([]byte(s.data), &form)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
hasErr := err != nil
|
result := form.Validate()
|
||||||
if hasErr != s.expectError {
|
|
||||||
t.Errorf("(%d) Expected hasErr to be %v, got %v (%v)", i, s.expectError, hasErr, err)
|
// parse errors
|
||||||
|
errs, ok := result.(validation.Errors)
|
||||||
|
if !ok && result != nil {
|
||||||
|
t.Fatalf("Failed to parse errors %v", result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// check errors
|
||||||
|
if len(errs) > len(s.expectedErrors) {
|
||||||
|
t.Fatalf("Expected error keys %v, got %v", s.expectedErrors, errs)
|
||||||
|
}
|
||||||
|
for _, k := range s.expectedErrors {
|
||||||
|
if _, ok := errs[k]; !ok {
|
||||||
|
t.Fatalf("Missing expected error key %q in %v", k, errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/mails"
|
"github.com/pocketbase/pocketbase/mails"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
@@ -129,6 +129,10 @@ func (form *RecordOAuth2Login) Submit(
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if form.Provider == auth.NameInstagram {
|
||||||
|
form.app.Logger().Warn("Instagram OAuth2 provider is deprecated and will stop working after December 4th. For more details please check https://github.com/pocketbase/pocketbase/discussions/5652.")
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -256,6 +260,27 @@ func (form *RecordOAuth2Login) submit(data *RecordOAuth2LoginData) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent pre-hijacking with different OAuth2 provider
|
||||||
|
//
|
||||||
|
// delete all other previous OAuth2 record links for the cases
|
||||||
|
// when the user was precreated by malicious OAuth2 auth with custom payload data
|
||||||
|
//
|
||||||
|
// while this would be also done automatically on unverified -> verified upgrade,
|
||||||
|
// doing it manually here ensures that a single unverified record could have
|
||||||
|
// max 1 OAuth2 link to prevent further abuse when mixed with other auth flows
|
||||||
|
if !data.Record.Verified() {
|
||||||
|
externalAuths, err := txDao.FindAllExternalAuthsByRecord(data.Record)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, ea := range externalAuths {
|
||||||
|
if err := txDao.DeleteExternalAuth(ea); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.ExternalAuth = nil // clear to allow recreate below
|
||||||
|
}
|
||||||
|
|
||||||
// update the existing auth record empty email if the data.OAuth2User has one
|
// update the existing auth record empty email if the data.OAuth2User has one
|
||||||
// (this is in case previously the auth record was created
|
// (this is in case previously the auth record was created
|
||||||
// with an OAuth2 provider that didn't return an email address)
|
// with an OAuth2 provider that didn't return an email address)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/mails"
|
"github.com/pocketbase/pocketbase/mails"
|
||||||
|
|||||||
+38
-20
@@ -9,9 +9,9 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
@@ -756,6 +756,8 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record]
|
|||||||
|
|
||||||
dao := form.dao.Clone()
|
dao := form.dao.Clone()
|
||||||
|
|
||||||
|
var uploaded []string
|
||||||
|
|
||||||
// upload new files (if any)
|
// upload new files (if any)
|
||||||
//
|
//
|
||||||
// note: executed after the default BeforeCreateFunc and BeforeUpdateFunc hook actions
|
// note: executed after the default BeforeCreateFunc and BeforeUpdateFunc hook actions
|
||||||
@@ -765,7 +767,9 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record]
|
|||||||
dao.BeforeCreateFunc = func(eventDao *daos.Dao, m models.Model, action func() error) error {
|
dao.BeforeCreateFunc = func(eventDao *daos.Dao, m models.Model, action func() error) error {
|
||||||
newAction := func() error {
|
newAction := func() error {
|
||||||
if m.TableName() == form.record.TableName() && m.GetId() == form.record.GetId() {
|
if m.TableName() == form.record.TableName() && m.GetId() == form.record.GetId() {
|
||||||
if err := form.processFilesToUpload(); err != nil {
|
var err error
|
||||||
|
uploaded, err = form.processFilesToUpload()
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -783,7 +787,9 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record]
|
|||||||
dao.BeforeUpdateFunc = func(eventDao *daos.Dao, m models.Model, action func() error) error {
|
dao.BeforeUpdateFunc = func(eventDao *daos.Dao, m models.Model, action func() error) error {
|
||||||
newAction := func() error {
|
newAction := func() error {
|
||||||
if m.TableName() == form.record.TableName() && m.GetId() == form.record.GetId() {
|
if m.TableName() == form.record.TableName() && m.GetId() == form.record.GetId() {
|
||||||
if err := form.processFilesToUpload(); err != nil {
|
var err error
|
||||||
|
uploaded, err = form.processFilesToUpload()
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -801,6 +807,9 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record]
|
|||||||
|
|
||||||
// persist the record model
|
// persist the record model
|
||||||
if err := dao.SaveRecord(form.record); err != nil {
|
if err := dao.SaveRecord(form.record); err != nil {
|
||||||
|
// cleanup - try to delete only the successfully uploaded files
|
||||||
|
form.deleteFilesByNamesList(uploaded)
|
||||||
|
|
||||||
return form.prepareError(err)
|
return form.prepareError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,30 +828,30 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record]
|
|||||||
}, interceptors...)
|
}, interceptors...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (form *RecordUpsert) processFilesToUpload() error {
|
func (form *RecordUpsert) processFilesToUpload() ([]string, error) {
|
||||||
if len(form.filesToUpload) == 0 {
|
if len(form.filesToUpload) == 0 {
|
||||||
return nil // no parsed file fields
|
return nil, nil // no parsed file fields
|
||||||
}
|
}
|
||||||
|
|
||||||
if !form.record.HasId() {
|
if !form.record.HasId() {
|
||||||
return errors.New("the record doesn't have an id")
|
return nil, errors.New("the record doesn't have an id")
|
||||||
}
|
}
|
||||||
|
|
||||||
fs, err := form.app.NewFilesystem()
|
fsys, err := form.app.NewFilesystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer fs.Close()
|
defer fsys.Close()
|
||||||
|
|
||||||
var uploadErrors []error // list of upload errors
|
var uploadErrors []error // list of upload errors
|
||||||
var uploaded []string // list of uploaded file paths
|
var uploaded []string // list of uploaded file names
|
||||||
|
|
||||||
for fieldKey := range form.filesToUpload {
|
for fieldKey := range form.filesToUpload {
|
||||||
for i, file := range form.filesToUpload[fieldKey] {
|
for i, file := range form.filesToUpload[fieldKey] {
|
||||||
path := form.record.BaseFilesPath() + "/" + file.Name
|
path := form.record.BaseFilesPath() + "/" + file.Name
|
||||||
if err := fs.UploadFile(file, path); err == nil {
|
if err := fsys.UploadFile(file, path); err == nil {
|
||||||
// keep track of the already uploaded file
|
// keep track of the already uploaded file
|
||||||
uploaded = append(uploaded, path)
|
uploaded = append(uploaded, file.Name)
|
||||||
} else {
|
} else {
|
||||||
// store the upload error
|
// store the upload error
|
||||||
uploadErrors = append(uploadErrors, fmt.Errorf("file %d: %v", i, err))
|
uploadErrors = append(uploadErrors, fmt.Errorf("file %d: %v", i, err))
|
||||||
@@ -854,10 +863,10 @@ func (form *RecordUpsert) processFilesToUpload() error {
|
|||||||
// cleanup - try to delete the successfully uploaded files (if any)
|
// cleanup - try to delete the successfully uploaded files (if any)
|
||||||
form.deleteFilesByNamesList(uploaded)
|
form.deleteFilesByNamesList(uploaded)
|
||||||
|
|
||||||
return fmt.Errorf("failed to upload all files: %v", uploadErrors)
|
return nil, fmt.Errorf("failed to upload all files: %v", uploadErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return uploaded, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (form *RecordUpsert) processFilesToDelete() (err error) {
|
func (form *RecordUpsert) processFilesToDelete() (err error) {
|
||||||
@@ -876,24 +885,28 @@ func (form *RecordUpsert) deleteFilesByNamesList(filenames []string) ([]string,
|
|||||||
return filenames, errors.New("the record doesn't have an id")
|
return filenames, errors.New("the record doesn't have an id")
|
||||||
}
|
}
|
||||||
|
|
||||||
fs, err := form.app.NewFilesystem()
|
isNew := form.record.IsNew()
|
||||||
|
|
||||||
|
baseDir := form.record.BaseFilesPath()
|
||||||
|
|
||||||
|
fsys, err := form.app.NewFilesystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return filenames, err
|
return filenames, err
|
||||||
}
|
}
|
||||||
defer fs.Close()
|
defer fsys.Close()
|
||||||
|
|
||||||
var deleteErrors []error
|
var deleteErrors []error
|
||||||
|
|
||||||
for i := len(filenames) - 1; i >= 0; i-- {
|
for i := len(filenames) - 1; i >= 0; i-- {
|
||||||
filename := filenames[i]
|
filename := filenames[i]
|
||||||
path := form.record.BaseFilesPath() + "/" + filename
|
path := baseDir + "/" + filename
|
||||||
|
|
||||||
if err := fs.Delete(path); err == nil {
|
if err := fsys.Delete(path); err == nil {
|
||||||
// remove the deleted file from the list
|
// remove the deleted file from the list
|
||||||
filenames = append(filenames[:i], filenames[i+1:]...)
|
filenames = append(filenames[:i], filenames[i+1:]...)
|
||||||
|
|
||||||
// try to delete the related file thumbs (if any)
|
// try to delete the related file thumbs (if any)
|
||||||
fs.DeletePrefix(form.record.BaseFilesPath() + "/thumbs_" + filename + "/")
|
fsys.DeletePrefix(baseDir + "/thumbs_" + filename + "/")
|
||||||
} else {
|
} else {
|
||||||
// store the delete error
|
// store the delete error
|
||||||
deleteErrors = append(deleteErrors, fmt.Errorf("file %d: %v", i, err))
|
deleteErrors = append(deleteErrors, fmt.Errorf("file %d: %v", i, err))
|
||||||
@@ -904,6 +917,11 @@ func (form *RecordUpsert) deleteFilesByNamesList(filenames []string) ([]string,
|
|||||||
return filenames, fmt.Errorf("failed to delete all files: %v", deleteErrors)
|
return filenames, fmt.Errorf("failed to delete all files: %v", deleteErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanup empty dir for new records if there are no other files
|
||||||
|
if isNew && fsys.IsEmptyDir(baseDir) {
|
||||||
|
_ = fsys.Delete(baseDir)
|
||||||
|
}
|
||||||
|
|
||||||
return filenames, nil
|
return filenames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
@@ -619,6 +619,94 @@ func TestRecordUpsertSubmitInterceptors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecordUpsertSubmitFailureFilesCleanup(t *testing.T) {
|
||||||
|
app, _ := tests.NewTestApp()
|
||||||
|
defer app.Cleanup()
|
||||||
|
|
||||||
|
collection, err := app.Dao().FindCollectionByNameOrId("demo3")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that there is a unique index constraint
|
||||||
|
collection.Indexes = append(collection.Indexes, `CREATE UNIQUE INDEX "idx_unique_demo3_title" on "demo3" ("title")`)
|
||||||
|
if err := app.Dao().SaveCollection(collection); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f1, err := filesystem.NewFileFromBytes([]byte("test1"), "new_test1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f2, err := filesystem.NewFileFromBytes([]byte("test1"), "new_test2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadedFiles := []string{f1.Name, f2.Name}
|
||||||
|
|
||||||
|
existing, err := app.Dao().FindRecordById(collection.Id, "mk5fmymtx4wsprk")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
recordId string
|
||||||
|
}{
|
||||||
|
{""},
|
||||||
|
{"7nwo8tuiatetxdm"},
|
||||||
|
{"1tmknxy2868d869"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
sname := s.recordId
|
||||||
|
if sname == "" {
|
||||||
|
sname = "new"
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(sname, func(t *testing.T) {
|
||||||
|
var originalFiles []string
|
||||||
|
|
||||||
|
var record *models.Record
|
||||||
|
if s.recordId == "" {
|
||||||
|
record = models.NewRecord(collection)
|
||||||
|
} else {
|
||||||
|
record, err = app.Dao().FindRecordById(collection.Id, s.recordId)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
originalFiles = record.GetStringSlice("files")
|
||||||
|
}
|
||||||
|
|
||||||
|
record.Set("title", existing.GetString("title"))
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(app, record)
|
||||||
|
|
||||||
|
form.AddFiles("files", f1, f2)
|
||||||
|
|
||||||
|
err := form.Submit()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected form submit to fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the original files still exists
|
||||||
|
for _, name := range originalFiles {
|
||||||
|
if !hasRecordFile(app, record, name) {
|
||||||
|
t.Fatalf("Missing original file %q", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the new uploaded files were deleted
|
||||||
|
for _, name := range uploadedFiles {
|
||||||
|
if hasRecordFile(app, record, name) {
|
||||||
|
t.Fatalf("Expected file %q to be deleted", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRecordUpsertWithCustomId(t *testing.T) {
|
func TestRecordUpsertWithCustomId(t *testing.T) {
|
||||||
app, _ := tests.NewTestApp()
|
app, _ := tests.NewTestApp()
|
||||||
defer app.Cleanup()
|
defer app.Cleanup()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/mails"
|
"github.com/pocketbase/pocketbase/mails"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/models/settings"
|
"github.com/pocketbase/pocketbase/models/settings"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package forms
|
package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/mails"
|
"github.com/pocketbase/pocketbase/mails"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/models/settings"
|
"github.com/pocketbase/pocketbase/models/settings"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package forms_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/forms"
|
"github.com/pocketbase/pocketbase/forms"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gabriel-vasile/mimetype"
|
"github.com/gabriel-vasile/mimetype"
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ package validators
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
@@ -159,6 +160,10 @@ func (validator *RecordDataValidator) checkNumberValue(field *schema.SchemaField
|
|||||||
return nil // nothing to check (skip zero-defaults)
|
return nil // nothing to check (skip zero-defaults)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if math.IsInf(val, 0) || math.IsNaN(val) {
|
||||||
|
return validation.NewError("validation_nan", "The submitted number is not properly formatted")
|
||||||
|
}
|
||||||
|
|
||||||
options, _ := field.Options.(*schema.NumberOptions)
|
options, _ := field.Options.(*schema.NumberOptions)
|
||||||
|
|
||||||
if options.NoDecimal && val != float64(int64(val)) {
|
if options.NoDecimal && val != float64(int64(val)) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/forms/validators"
|
"github.com/pocketbase/pocketbase/forms/validators"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
@@ -248,6 +248,16 @@ func TestRecordDataValidatorValidateNumber(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
[]string{"field2"},
|
[]string{"field2"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"(number) check infinities and NaN",
|
||||||
|
map[string]any{
|
||||||
|
"field1": "Inf",
|
||||||
|
"field2": "-Inf",
|
||||||
|
"field4": "NaN",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
[]string{"field1", "field2", "field4"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"(number) check min constraint",
|
"(number) check min constraint",
|
||||||
map[string]any{
|
map[string]any{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package validators
|
package validators
|
||||||
|
|
||||||
import (
|
import (
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Compare checks whether the validated value matches another string.
|
// Compare checks whether the validated value matches another string.
|
||||||
|
|||||||
@@ -1,90 +1,86 @@
|
|||||||
module github.com/pocketbase/pocketbase
|
module github.com/pocketbase/pocketbase
|
||||||
|
|
||||||
go 1.22
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/aws/aws-sdk-go-v2 v1.30.4
|
github.com/aws/aws-sdk-go-v2 v1.32.6
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.31
|
github.com/aws/aws-sdk-go-v2/config v1.28.6
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.30
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.47
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0
|
||||||
github.com/aws/smithy-go v1.20.4
|
github.com/aws/smithy-go v1.22.1
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/domodwyer/mailyak/v3 v3.6.2
|
github.com/domodwyer/mailyak/v3 v3.6.2
|
||||||
github.com/dop251/goja v0.0.0-20240822155948-fa6d1ed5e4b6
|
github.com/dop251/goja v0.0.0-20241009100908-5f46f2705ca3
|
||||||
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc
|
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc
|
||||||
github.com/fatih/color v1.17.0
|
github.com/fatih/color v1.18.0
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
github.com/gabriel-vasile/mimetype v1.4.5
|
github.com/gabriel-vasile/mimetype v1.4.7
|
||||||
github.com/ganigeorgiev/fexpr v0.4.1
|
github.com/ganigeorgiev/fexpr v0.4.1
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
|
github.com/goccy/go-json v0.10.4
|
||||||
github.com/goccy/go-json v0.10.3
|
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
|
||||||
github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61
|
github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
github.com/mattn/go-sqlite3 v1.14.24
|
||||||
github.com/pocketbase/dbx v1.10.1
|
github.com/pocketbase/dbx v1.11.0
|
||||||
github.com/pocketbase/tygoja v0.0.0-20240113091827-17918475d342
|
github.com/pocketbase/ozzo-validation/v4 v4.3.0
|
||||||
github.com/spf13/cast v1.7.0
|
github.com/pocketbase/tygoja v0.0.0-20241015175937-d6ff411a0f75
|
||||||
|
github.com/spf13/cast v1.7.1
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
gocloud.dev v0.39.0
|
gocloud.dev v0.40.0
|
||||||
golang.org/x/crypto v0.26.0
|
golang.org/x/crypto v0.52.0
|
||||||
golang.org/x/net v0.28.0
|
golang.org/x/net v0.55.0
|
||||||
golang.org/x/oauth2 v0.22.0
|
golang.org/x/oauth2 v0.36.0
|
||||||
golang.org/x/sync v0.8.0
|
golang.org/x/sync v0.20.0
|
||||||
modernc.org/sqlite v1.32.0
|
modernc.org/sqlite v1.48.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect
|
||||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
|
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.14.0 // indirect
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
golang.org/x/image v0.19.0 // indirect
|
golang.org/x/image v0.41.0 // indirect
|
||||||
golang.org/x/mod v0.19.0 // indirect
|
golang.org/x/mod v0.36.0 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/sys v0.45.0 // indirect
|
||||||
golang.org/x/term v0.23.0 // indirect
|
golang.org/x/term v0.43.0 // indirect
|
||||||
golang.org/x/text v0.17.0 // indirect
|
golang.org/x/text v0.37.0 // indirect
|
||||||
golang.org/x/time v0.6.0 // indirect
|
golang.org/x/time v0.8.0 // indirect
|
||||||
golang.org/x/tools v0.23.0 // indirect
|
golang.org/x/tools v0.45.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||||
google.golang.org/api v0.194.0 // indirect
|
google.golang.org/api v0.213.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||||
google.golang.org/grpc v1.65.0 // indirect
|
google.golang.org/grpc v1.69.2 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.36.0 // indirect
|
||||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect
|
modernc.org/libc v1.70.0 // indirect
|
||||||
modernc.org/libc v1.55.3 // indirect
|
modernc.org/mathutil v1.7.1 // indirect
|
||||||
modernc.org/mathutil v1.6.0 // indirect
|
modernc.org/memory v1.11.0 // indirect
|
||||||
modernc.org/memory v1.8.0 // indirect
|
|
||||||
modernc.org/strutil v1.2.0 // indirect
|
|
||||||
modernc.org/token v1.1.0 // indirect
|
|
||||||
)
|
)
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
|
cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
|
||||||
cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
|
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
|
||||||
cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w=
|
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
|
||||||
cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk=
|
cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
|
cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
|
||||||
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||||
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||||
cloud.google.com/go/iam v1.1.13 h1:7zWBXG9ERbMLrzQBRhFliAV+kjcRToDTgQT3CTwYyv4=
|
cloud.google.com/go/iam v1.1.13 h1:7zWBXG9ERbMLrzQBRhFliAV+kjcRToDTgQT3CTwYyv4=
|
||||||
cloud.google.com/go/iam v1.1.13/go.mod h1:K8mY0uSXwEXS30KrnVb+j54LB/ntfZu1dr+4zFMNbus=
|
cloud.google.com/go/iam v1.1.13/go.mod h1:K8mY0uSXwEXS30KrnVb+j54LB/ntfZu1dr+4zFMNbus=
|
||||||
cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
|
cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
|
||||||
@@ -25,44 +25,44 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||||
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8=
|
github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0=
|
github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.31 h1:kxBoRsjhT3pq0cKthgj6RU6bXTm/2SgdoUMyrVw0rAI=
|
github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.31/go.mod h1:z04nZdSWFPaDwK3DdJOG2r+scLQzMYuJeW0CujEm9FM=
|
github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.30 h1:aau/oYFtibVovr2rDt8FHlU17BTicFEMAi29V1U+L5Q=
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.30/go.mod h1:BPJ/yXV92ZVq6G8uYvbU0gSl8q94UB63nMT5ctNO38g=
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15 h1:ijB7hr56MngOiELJe0C5aQRaBQ11LveNgWFyG02AUto=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 h1:iLdpkYZ4cXIQMO7ud+cqMWR1xK5ESbt1rvN77tRi1BY=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15/go.mod h1:0QEmQSSWMVfiAk93l1/ayR9DQ9+jwni7gHS2NARZXB0=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43/go.mod h1:OgbsKPAswXDd5kxnR4vZov69p3oYjbvUyIRBAAV0y9o=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25/go.mod h1:GrGY+Q4fIokYLtjCVB/aFfCVL6hhGUFl8inD18fDalE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 h1:HCpPsWqmYQieU7SS6E9HXfdAMSud0pteVXieJmcpIRI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6/go.mod h1:ngUiVRCco++u+soRRVBIvBZxSMMvOVMXA4PJ36JLfSw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 h1:BbGDtTi0T1DYlmjBiCr/le3wzhA37O8QTC5/Ab8+EXk=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6/go.mod h1:hLMJt7Q8ePgViKupeymbqI0la+t9/iYFBjxQCFwuAwI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 h1:nyuzXooUNJexRT0Oy0UQY6AhOzxPxhtt4DcBIHyCnmw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 h1:OMsEmCyz2i89XwRwPouAJvhj81wINh+4UK+k/0Yo/q8=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.5/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8=
|
||||||
github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4=
|
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
|
||||||
github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
@@ -78,8 +78,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA
|
|||||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8=
|
github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8=
|
||||||
github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
|
github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
|
||||||
github.com/dop251/goja v0.0.0-20240822155948-fa6d1ed5e4b6 h1:0x8Sh2rKCTVUQnRTJFIwtRWAp91VMsnATQEsMAg14kM=
|
github.com/dop251/goja v0.0.0-20241009100908-5f46f2705ca3 h1:MXsAuToxwsTn5BEEYm2DheqIiC4jWGmkEJ1uy+KFhvQ=
|
||||||
github.com/dop251/goja v0.0.0-20240822155948-fa6d1ed5e4b6/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
github.com/dop251/goja v0.0.0-20241009100908-5f46f2705ca3/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
||||||
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc h1:MKYt39yZJi0Z9xEeRmDX2L4ocE0ETKcHKw6MVL3R+co=
|
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc h1:MKYt39yZJi0Z9xEeRmDX2L4ocE0ETKcHKw6MVL3R+co=
|
||||||
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc/go.mod h1:VULptt4Q/fNzQUJlqY/GP3qHyU7ZH46mFkBZe0ZTokU=
|
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc/go.mod h1:VULptt4Q/fNzQUJlqY/GP3qHyU7ZH46mFkBZe0ZTokU=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
@@ -88,37 +88,35 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
|
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
|
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||||
github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k=
|
github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k=
|
||||||
github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
|
github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es=
|
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
|
|
||||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q=
|
github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q=
|
||||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -140,8 +138,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||||
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||||
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@@ -149,10 +147,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
|
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
|
||||||
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
|
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||||
github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
|
github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o=
|
||||||
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
|
github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk=
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||||
@@ -176,27 +174,29 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
|||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA=
|
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
|
||||||
github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
|
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
|
||||||
github.com/pocketbase/tygoja v0.0.0-20240113091827-17918475d342 h1:OcAwewen3hs/zY8i0syt8CcMTGBJhQwQRVDLcoQVXVk=
|
github.com/pocketbase/ozzo-validation/v4 v4.3.0 h1:uKBDVma7bZqgR2a6AwE+k9hkuDFfiZMpBHQdZ1z3iQs=
|
||||||
github.com/pocketbase/tygoja v0.0.0-20240113091827-17918475d342/go.mod h1:dOJ+pCyqm/jRn5kO/TX598J0e5xGDcJAZerK5atCrKI=
|
github.com/pocketbase/ozzo-validation/v4 v4.3.0/go.mod h1:6XNjSTw/Jb2F8LOkKO3oyzIWExbrGiYoS4uVxVwz90g=
|
||||||
|
github.com/pocketbase/tygoja v0.0.0-20241015175937-d6ff411a0f75 h1:XSbmekxgmbI2uPrre/nkCz7y8VsV652TPb3hAYzPb74=
|
||||||
|
github.com/pocketbase/tygoja v0.0.0-20241015175937-d6ff411a0f75/go.mod h1:hKJWPGFqavk3cdTa47Qvs8g37lnfI57OYdVVbIqW5aE=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
@@ -218,33 +218,37 @@ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
|
|||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||||
gocloud.dev v0.39.0 h1:EYABYGhAalPUaMrbSKOr5lejxoxvXj99nE8XFtsDgds=
|
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||||
gocloud.dev v0.39.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ=
|
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||||
|
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||||
|
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||||
|
gocloud.dev v0.40.0 h1:f8LgP+4WDqOG/RXoUcyLpeIAGOcAbZrZbDQCUee10ng=
|
||||||
|
gocloud.dev v0.40.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
|
golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo=
|
||||||
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
|
golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -255,17 +259,17 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -277,21 +281,21 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@@ -299,33 +303,33 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk=
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
|
||||||
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||||
google.golang.org/api v0.194.0 h1:dztZKG9HgtIpbI35FhfuSNR/zmaMVdxNlntHj1sIS4s=
|
google.golang.org/api v0.213.0 h1:KmF6KaDyFqB417T68tMPbVmmwtIXs2VB60OJKIHB0xQ=
|
||||||
google.golang.org/api v0.194.0/go.mod h1:AgvUFdojGANh3vI+P7EVnxj3AISHllxGCJSFmggmnd0=
|
google.golang.org/api v0.213.0/go.mod h1:V0T5ZhNUUNpYAlL306gFZPFt5F5D/IeyLoktduYYnvQ=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0=
|
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM=
|
||||||
google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4=
|
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk=
|
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 h1:Z7FRVJPSMaHQxD0uXU8WdgFh8PseLM8Q8NzhnpMrBhQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@@ -335,8 +339,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
@@ -346,29 +350,31 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
|
||||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
|
modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw=
|
||||||
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
|
modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0=
|
||||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
|
||||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
|
||||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a h1:CfbpOLEo2IwNzJdMvE8aiRbPMxoTpgAJeyePh0SmO8M=
|
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
|
||||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw=
|
||||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo=
|
||||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||||
modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s=
|
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||||
modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
modernc.org/sqlite v1.48.2 h1:5CnW4uP8joZtA0LedVqLbZV5GD7F/0x91AXeSyjoh5c=
|
||||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
modernc.org/sqlite v1.48.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
|
||||||
|
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||||
|
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
@@ -3,8 +3,8 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
"github.com/pocketbase/pocketbase/tools/security"
|
"github.com/pocketbase/pocketbase/tools/security"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/tools/auth"
|
"github.com/pocketbase/pocketbase/tools/auth"
|
||||||
"github.com/pocketbase/pocketbase/tools/cron"
|
"github.com/pocketbase/pocketbase/tools/cron"
|
||||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/models/settings"
|
"github.com/pocketbase/pocketbase/models/settings"
|
||||||
"github.com/pocketbase/pocketbase/tools/auth"
|
"github.com/pocketbase/pocketbase/tools/auth"
|
||||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||||
|
|||||||
@@ -164,6 +164,11 @@ func (p *plugin) update(withBackup bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if compareVersions(strings.TrimPrefix(latest.Tag, "v"), "0.23.0") <= 0 {
|
||||||
|
color.Green("%s contains breaking changes and cannot be updated directly from v0.22.x. Please check the releases CHANGELOG for more details.", latest.Tag)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
suffix := archiveSuffix(runtime.GOOS, runtime.GOARCH)
|
suffix := archiveSuffix(runtime.GOOS, runtime.GOARCH)
|
||||||
if suffix == "" {
|
if suffix == "" {
|
||||||
return errors.New("unsupported platform")
|
return errors.New("unsupported platform")
|
||||||
|
|||||||
+33
-5
@@ -16,10 +16,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/labstack/echo/v5/middleware"
|
"github.com/labstack/echo/v5/middleware"
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
@@ -61,7 +61,7 @@ func hooksBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
|
|||||||
|
|
||||||
// register the hook to the loader
|
// register the hook to the loader
|
||||||
loader.Set(jsName, func(callback string, tags ...string) {
|
loader.Set(jsName, func(callback string, tags ...string) {
|
||||||
pr := goja.MustCompile("", "{("+callback+").apply(undefined, __args)}", true)
|
pr := goja.MustCompile(defaultScriptPath, "{("+callback+").apply(undefined, __args)}", true)
|
||||||
|
|
||||||
tagsAsValues := make([]reflect.Value, len(tags))
|
tagsAsValues := make([]reflect.Value, len(tags))
|
||||||
for i, tag := range tags {
|
for i, tag := range tags {
|
||||||
@@ -114,7 +114,7 @@ func cronBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
|
|||||||
var wasServeTriggered bool
|
var wasServeTriggered bool
|
||||||
|
|
||||||
loader.Set("cronAdd", func(jobId, cronExpr, handler string) {
|
loader.Set("cronAdd", func(jobId, cronExpr, handler string) {
|
||||||
pr := goja.MustCompile("", "{("+handler+").apply(undefined)}", true)
|
pr := goja.MustCompile(defaultScriptPath, "{("+handler+").apply(undefined)}", true)
|
||||||
|
|
||||||
err := scheduler.Add(jobId, cronExpr, func() {
|
err := scheduler.Add(jobId, cronExpr, func() {
|
||||||
err := executors.run(func(executor *goja.Runtime) error {
|
err := executors.run(func(executor *goja.Runtime) error {
|
||||||
@@ -215,7 +215,7 @@ func wrapHandler(executors *vmsPool, handler goja.Value) (echo.HandlerFunc, erro
|
|||||||
// "native" handler - no need to wrap
|
// "native" handler - no need to wrap
|
||||||
return h, nil
|
return h, nil
|
||||||
case func(goja.FunctionCall) goja.Value, string:
|
case func(goja.FunctionCall) goja.Value, string:
|
||||||
pr := goja.MustCompile("", "{("+handler.String()+").apply(undefined, __args)}", true)
|
pr := goja.MustCompile(defaultScriptPath, "{("+handler.String()+").apply(undefined, __args)}", true)
|
||||||
|
|
||||||
wrappedHandler := func(c echo.Context) error {
|
wrappedHandler := func(c echo.Context) error {
|
||||||
return executors.run(func(executor *goja.Runtime) error {
|
return executors.run(func(executor *goja.Runtime) error {
|
||||||
@@ -253,7 +253,7 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]echo.M
|
|||||||
// "native" middleware - no need to wrap
|
// "native" middleware - no need to wrap
|
||||||
wrappedMiddlewares[i] = v
|
wrappedMiddlewares[i] = v
|
||||||
case func(goja.FunctionCall) goja.Value, string:
|
case func(goja.FunctionCall) goja.Value, string:
|
||||||
pr := goja.MustCompile("", "{(("+m.String()+").apply(undefined, __args)).apply(undefined, __args2)}", true)
|
pr := goja.MustCompile(defaultScriptPath, "{(("+m.String()+").apply(undefined, __args)).apply(undefined, __args2)}", true)
|
||||||
|
|
||||||
wrappedMiddlewares[i] = func(next echo.HandlerFunc) echo.HandlerFunc {
|
wrappedMiddlewares[i] = func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
@@ -301,6 +301,34 @@ func baseBinds(vm *goja.Runtime) {
|
|||||||
return string(bodyBytes), nil
|
return string(bodyBytes), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
vm.Set("toString", func(raw any, maxReaderBytes int) (string, error) {
|
||||||
|
switch v := raw.(type) {
|
||||||
|
case io.Reader:
|
||||||
|
if maxReaderBytes == 0 {
|
||||||
|
maxReaderBytes = rest.DefaultMaxMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
limitReader := io.LimitReader(v, int64(maxReaderBytes))
|
||||||
|
|
||||||
|
bodyBytes, readErr := io.ReadAll(limitReader)
|
||||||
|
if readErr != nil {
|
||||||
|
return "", readErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(bodyBytes), nil
|
||||||
|
default:
|
||||||
|
str, err := cast.ToStringE(v)
|
||||||
|
if err == nil {
|
||||||
|
return str, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// as a last attempt try to json encode the value
|
||||||
|
rawBytes, _ := json.Marshal(raw)
|
||||||
|
|
||||||
|
return string(rawBytes), nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
vm.Set("sleep", func(milliseconds int64) {
|
vm.Set("sleep", func(milliseconds int64) {
|
||||||
time.Sleep(time.Duration(milliseconds) * time.Millisecond)
|
time.Sleep(time.Duration(milliseconds) * time.Millisecond)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
@@ -47,7 +47,7 @@ func TestBaseBindsCount(t *testing.T) {
|
|||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
baseBinds(vm)
|
baseBinds(vm)
|
||||||
|
|
||||||
testBindsCount(vm, "this", 17, t)
|
testBindsCount(vm, "this", 18, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBaseBindsSleep(t *testing.T) {
|
func TestBaseBindsSleep(t *testing.T) {
|
||||||
@@ -92,6 +92,41 @@ func TestBaseBindsReaderToString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBaseBindsToString(t *testing.T) {
|
||||||
|
vm := goja.New()
|
||||||
|
baseBinds(vm)
|
||||||
|
vm.Set("scenarios", []struct {
|
||||||
|
Name string
|
||||||
|
Value any
|
||||||
|
Expected string
|
||||||
|
}{
|
||||||
|
{"null", nil, ""},
|
||||||
|
{"string", "test", "test"},
|
||||||
|
{"number", -12.4, "-12.4"},
|
||||||
|
{"bool", true, "true"},
|
||||||
|
{"arr", []int{1, 2, 3}, `[1,2,3]`},
|
||||||
|
{"obj", map[string]any{"test": 123}, `{"test":123}`},
|
||||||
|
{"reader", strings.NewReader("test"), "test"},
|
||||||
|
{"struct", struct {
|
||||||
|
Name string
|
||||||
|
private string
|
||||||
|
}{Name: "123", private: "456"}, `{"Name":"123"}`},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := vm.RunString(`
|
||||||
|
for (let s of scenarios) {
|
||||||
|
let result = toString(s.value)
|
||||||
|
|
||||||
|
if (result != s.expected) {
|
||||||
|
throw new Error('[' + s.name + '] Expected string ' + s.expected + ', got ' + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBaseBindsCookie(t *testing.T) {
|
func TestBaseBindsCookie(t *testing.T) {
|
||||||
app, _ := tests.NewTestApp()
|
app, _ := tests.NewTestApp()
|
||||||
defer app.Cleanup()
|
defer app.Cleanup()
|
||||||
|
|||||||
+5940
-5808
File diff suppressed because it is too large.
Load diff
@@ -194,22 +194,34 @@ declare var $app: PocketBase
|
|||||||
declare var $template: template.Registry
|
declare var $template: template.Registry
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* readerToString reads the content of the specified io.Reader until
|
* This method is superseded by toString.
|
||||||
* EOF or maxBytes are reached.
|
|
||||||
*
|
*
|
||||||
* If maxBytes is not specified it will read up to 32MB.
|
* @deprecated
|
||||||
|
* @group PocketBase
|
||||||
|
*/
|
||||||
|
declare function readerToString(reader: any, maxBytes?: number): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toString stringifies the specified value.
|
||||||
*
|
*
|
||||||
* Note that after this call the reader can't be used anymore.
|
* Support optional second maxBytes argument to limit the max read bytes
|
||||||
|
* when the value is a io.Reader (default to 32MB).
|
||||||
|
*
|
||||||
|
* Types that don't have explicit string representation are json serialized.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* ` + "```" + `js
|
* ` + "```" + `js
|
||||||
* const rawBody = readerToString(c.request().body)
|
* // io.Reader
|
||||||
|
* const ex1 = toString(e.request.body)
|
||||||
|
*
|
||||||
|
* // slice of bytes ("hello")
|
||||||
|
* const ex2 = toString([104 101 108 108 111])
|
||||||
* ` + "```" + `
|
* ` + "```" + `
|
||||||
*
|
*
|
||||||
* @group PocketBase
|
* @group PocketBase
|
||||||
*/
|
*/
|
||||||
declare function readerToString(reader: any, maxBytes?: number): string;
|
declare function toString(val: any, maxBytes?: number): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sleep pauses the current goroutine for at least the specified user duration (in ms).
|
* sleep pauses the current goroutine for at least the specified user duration (in ms).
|
||||||
@@ -713,7 +725,7 @@ declare namespace $os {
|
|||||||
* const cmd = $os.cmd('ls', '-sl')
|
* const cmd = $os.cmd('ls', '-sl')
|
||||||
*
|
*
|
||||||
* // execute the command and return its standard output as string
|
* // execute the command and return its standard output as string
|
||||||
* const output = String.fromCharCode(...cmd.output());
|
* const output = toString(cmd.output());
|
||||||
* ` + "```" + `
|
* ` + "```" + `
|
||||||
*/
|
*/
|
||||||
export let cmd: exec.command
|
export let cmd: exec.command
|
||||||
@@ -1078,7 +1090,7 @@ func main() {
|
|||||||
gen := tygoja.New(tygoja.Config{
|
gen := tygoja.New(tygoja.Config{
|
||||||
Packages: map[string][]string{
|
Packages: map[string][]string{
|
||||||
"github.com/labstack/echo/v5/middleware": {"Gzip", "BodyLimit"},
|
"github.com/labstack/echo/v5/middleware": {"Gzip", "BodyLimit"},
|
||||||
"github.com/go-ozzo/ozzo-validation/v4": {"Error"},
|
"github.com/pocketbase/ozzo-validation/v4": {"Error"},
|
||||||
"github.com/pocketbase/dbx": {"*"},
|
"github.com/pocketbase/dbx": {"*"},
|
||||||
"github.com/pocketbase/pocketbase/tools/security": {"*"},
|
"github.com/pocketbase/pocketbase/tools/security": {"*"},
|
||||||
"github.com/pocketbase/pocketbase/tools/filesystem": {"*"},
|
"github.com/pocketbase/pocketbase/tools/filesystem": {"*"},
|
||||||
|
|||||||
+39
-12
@@ -32,12 +32,29 @@ import (
|
|||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
m "github.com/pocketbase/pocketbase/migrations"
|
m "github.com/pocketbase/pocketbase/migrations"
|
||||||
"github.com/pocketbase/pocketbase/plugins/jsvm/internal/types/generated"
|
"github.com/pocketbase/pocketbase/plugins/jsvm/internal/types/generated"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
"github.com/pocketbase/pocketbase/tools/template"
|
"github.com/pocketbase/pocketbase/tools/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const typesFileName = "types.d.ts"
|
||||||
typesFileName = "types.d.ts"
|
|
||||||
)
|
var defaultScriptPath = "pb.js"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// For backward compatibility and consistency with the Go exposed
|
||||||
|
// methods that accept relative paths (e.g. `$os.writeFile`),
|
||||||
|
// we define the "current JS module" as if it is a file in the current working directory
|
||||||
|
// (the filename itself doesn't really matter and in our case the hook handlers are executed as separate "programs").
|
||||||
|
//
|
||||||
|
// This is necessary for `require(module)` to properly traverse parents node_modules (goja_nodejs#95).
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
// truly rare case, log just for debug purposes
|
||||||
|
color.Yellow("Failed to retrieve the current working directory: %v", err)
|
||||||
|
} else {
|
||||||
|
defaultScriptPath = filepath.Join(cwd, defaultScriptPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Config defines the config options of the jsvm plugin.
|
// Config defines the config options of the jsvm plugin.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -187,7 +204,7 @@ func (p *plugin) registerMigrations() error {
|
|||||||
p.config.OnInit(vm)
|
p.config.OnInit(vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := vm.RunString(string(content))
|
_, err := vm.RunScript(defaultScriptPath, string(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run migration %s: %w", file, err)
|
return fmt.Errorf("failed to run migration %s: %w", file, err)
|
||||||
}
|
}
|
||||||
@@ -224,7 +241,7 @@ func (p *plugin) registerHooks() error {
|
|||||||
// initialize the hooks dir watcher
|
// initialize the hooks dir watcher
|
||||||
if p.config.HooksWatch {
|
if p.config.HooksWatch {
|
||||||
if err := p.watchHooks(); err != nil {
|
if err := p.watchHooks(); err != nil {
|
||||||
return err
|
color.Yellow("Unable to init hooks watcher: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +318,7 @@ func (p *plugin) registerHooks() error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err := loader.RunString(string(content))
|
_, err := loader.RunScript(defaultScriptPath, string(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -344,13 +361,23 @@ func (p *plugin) normalizeServeExceptions(oldErrorHandler echo.HTTPErrorHandler)
|
|||||||
//
|
//
|
||||||
// This method does nothing if the hooks directory is missing.
|
// This method does nothing if the hooks directory is missing.
|
||||||
func (p *plugin) watchHooks() error {
|
func (p *plugin) watchHooks() error {
|
||||||
if _, err := os.Stat(p.config.HooksDir); err != nil {
|
watchDir := p.config.HooksDir
|
||||||
|
|
||||||
|
hooksDirInfo, err := os.Lstat(p.config.HooksDir)
|
||||||
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
return nil // no hooks dir to watch
|
return nil // no hooks dir to watch
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hooksDirInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||||
|
watchDir, err = filepath.EvalSymlinks(p.config.HooksDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to resolve hooksDir symlink: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -374,7 +401,7 @@ func (p *plugin) watchHooks() error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// start listening for events.
|
// start listening for events.
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
defer stopDebounceTimer()
|
defer stopDebounceTimer()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -404,14 +431,14 @@ func (p *plugin) watchHooks() error {
|
|||||||
color.Red("Watch error:", err)
|
color.Red("Watch error:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
// add directories to watch
|
// add directories to watch
|
||||||
//
|
//
|
||||||
// @todo replace once recursive watcher is added (https://github.com/fsnotify/fsnotify/issues/18)
|
// @todo replace once recursive watcher is added (https://github.com/fsnotify/fsnotify/issues/18)
|
||||||
dirsErr := filepath.Walk(p.config.HooksDir, func(path string, info fs.FileInfo, err error) error {
|
dirsErr := filepath.WalkDir(watchDir, func(path string, entry fs.DirEntry, err error) error {
|
||||||
// ignore hidden directories and node_modules
|
// ignore hidden directories, node_modules, symlinks, sockets, etc.
|
||||||
if !info.IsDir() || info.Name() == "node_modules" || strings.HasPrefix(info.Name(), ".") {
|
if !entry.IsDir() || entry.Name() == "node_modules" || strings.HasPrefix(entry.Name(), ".") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/pocketbase/pocketbase/cmd"
|
"github.com/pocketbase/pocketbase/cmd"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -156,21 +157,21 @@ func (pb *PocketBase) Execute() error {
|
|||||||
done := make(chan bool, 1)
|
done := make(chan bool, 1)
|
||||||
|
|
||||||
// listen for interrupt signal to gracefully shutdown the application
|
// listen for interrupt signal to gracefully shutdown the application
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
sigch := make(chan os.Signal, 1)
|
sigch := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
||||||
<-sigch
|
<-sigch
|
||||||
|
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
})
|
||||||
|
|
||||||
// execute the root command
|
// execute the root command
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
// note: leave to the commands to decide whether to print their error
|
// note: leave to the commands to decide whether to print their error
|
||||||
pb.RootCmd.Execute()
|
pb.RootCmd.Execute()
|
||||||
|
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
})
|
||||||
|
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ func (p *Bitbucket) fetchPrimaryEmail(token *oauth2.Token) (string, error) {
|
|||||||
Values []struct {
|
Values []struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
IsPrimary bool `json:"is_primary"`
|
IsPrimary bool `json:"is_primary"`
|
||||||
|
IsConfirmed bool `json:"is_confirmed"`
|
||||||
} `json:"values"`
|
} `json:"values"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(data, &expected); err != nil {
|
if err := json.Unmarshal(data, &expected); err != nil {
|
||||||
@@ -123,7 +124,7 @@ func (p *Bitbucket) fetchPrimaryEmail(token *oauth2.Token) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range expected.Values {
|
for _, v := range expected.Values {
|
||||||
if v.IsPrimary {
|
if v.IsPrimary && v.IsConfirmed {
|
||||||
return v.Email, nil
|
return v.Email, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-3
@@ -50,6 +50,7 @@ func (p *Discord) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
|
|
||||||
extracted := struct {
|
extracted := struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
GlobalName string `json:"global_name"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Discriminator string `json:"discriminator"`
|
Discriminator string `json:"discriminator"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar"`
|
||||||
@@ -64,12 +65,22 @@ func (p *Discord) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
// https://discord.com/developers/docs/reference#image-formatting
|
// https://discord.com/developers/docs/reference#image-formatting
|
||||||
avatarUrl := fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.png", extracted.Id, extracted.Avatar)
|
avatarUrl := fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.png", extracted.Id, extracted.Avatar)
|
||||||
|
|
||||||
// Concatenate the user's username and discriminator into a single username string
|
name := extracted.GlobalName
|
||||||
username := fmt.Sprintf("%s#%s", extracted.Username, extracted.Discriminator)
|
if name == "" {
|
||||||
|
// fallback to username+discriminator
|
||||||
|
//
|
||||||
|
// Note: Discord migrated to unique usernames without discriminators.
|
||||||
|
// Legacy accounts still have a non-zero discriminator (e.g. "1234").
|
||||||
|
// See https://support.discord.com/hc/en-us/articles/12620128861463-New-Usernames-Display-Names.
|
||||||
|
name = extracted.Username
|
||||||
|
if extracted.Discriminator != "" && extracted.Discriminator != "0" {
|
||||||
|
name += "#" + extracted.Discriminator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user := &AuthUser{
|
user := &AuthUser{
|
||||||
Id: extracted.Id,
|
Id: extracted.Id,
|
||||||
Name: username,
|
Name: name,
|
||||||
Username: extracted.Username,
|
Username: extracted.Username,
|
||||||
AvatarUrl: avatarUrl,
|
AvatarUrl: avatarUrl,
|
||||||
RawUser: rawUser,
|
RawUser: rawUser,
|
||||||
|
|||||||
+55
-3
@@ -3,6 +3,8 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
@@ -47,11 +49,10 @@ func (p *Gitea) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extracted := struct {
|
extracted := struct {
|
||||||
Id int `json:"id"`
|
|
||||||
Name string `json:"full_name"`
|
Name string `json:"full_name"`
|
||||||
Username string `json:"login"`
|
Username string `json:"login"`
|
||||||
Email string `json:"email"`
|
|
||||||
AvatarUrl string `json:"avatar_url"`
|
AvatarUrl string `json:"avatar_url"`
|
||||||
|
Id int `json:"id"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -61,14 +62,65 @@ func (p *Gitea) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
Id: strconv.Itoa(extracted.Id),
|
Id: strconv.Itoa(extracted.Id),
|
||||||
Name: extracted.Name,
|
Name: extracted.Name,
|
||||||
Username: extracted.Username,
|
Username: extracted.Username,
|
||||||
Email: extracted.Email,
|
|
||||||
AvatarUrl: extracted.AvatarUrl,
|
AvatarUrl: extracted.AvatarUrl,
|
||||||
RawUser: rawUser,
|
RawUser: rawUser,
|
||||||
AccessToken: token.AccessToken,
|
AccessToken: token.AccessToken,
|
||||||
RefreshToken: token.RefreshToken,
|
RefreshToken: token.RefreshToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
email, err := p.fetchVerifiedPrimaryEmail(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch primary email: %w", err)
|
||||||
|
}
|
||||||
|
user.Email = email
|
||||||
|
|
||||||
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetchVerifiedPrimaryEmail sends an API request to retrieve the verified
|
||||||
|
// primary email, in case "Keep my email address private" was set.
|
||||||
|
//
|
||||||
|
// NB! This method can succeed and still return an empty email.
|
||||||
|
// Error responses that are result of insufficient scopes permissions are ignored.
|
||||||
|
//
|
||||||
|
// API reference: https://codeberg.org/api/swagger#/user/userListEmails
|
||||||
|
func (p *Gitea) fetchVerifiedPrimaryEmail(token *oauth2.Token) (string, error) {
|
||||||
|
client := p.Client(token)
|
||||||
|
|
||||||
|
response, err := client.Get(p.userApiUrl + "/emails")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
// ignore common http errors caused by insufficient scope permissions
|
||||||
|
// (the email field is optional, aka. return the auth user without it)
|
||||||
|
if response.StatusCode == 401 || response.StatusCode == 403 || response.StatusCode == 404 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := io.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
emails := []struct {
|
||||||
|
Email string
|
||||||
|
Verified bool
|
||||||
|
Primary bool
|
||||||
|
}{}
|
||||||
|
if err := json.Unmarshal(content, &emails); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the verified primary email
|
||||||
|
for _, email := range emails {
|
||||||
|
if email.Verified && email.Primary {
|
||||||
|
return email.Email, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
"github.com/pocketbase/ozzo-validation/v4/is"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,10 +50,9 @@ func (p *Github) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
|
|
||||||
extracted := struct {
|
extracted := struct {
|
||||||
Login string `json:"login"`
|
Login string `json:"login"`
|
||||||
Id int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Email string `json:"email"`
|
|
||||||
AvatarUrl string `json:"avatar_url"`
|
AvatarUrl string `json:"avatar_url"`
|
||||||
|
Id int `json:"id"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -63,7 +62,6 @@ func (p *Github) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
Id: strconv.Itoa(extracted.Id),
|
Id: strconv.Itoa(extracted.Id),
|
||||||
Name: extracted.Name,
|
Name: extracted.Name,
|
||||||
Username: extracted.Login,
|
Username: extracted.Login,
|
||||||
Email: extracted.Email,
|
|
||||||
AvatarUrl: extracted.AvatarUrl,
|
AvatarUrl: extracted.AvatarUrl,
|
||||||
RawUser: rawUser,
|
RawUser: rawUser,
|
||||||
AccessToken: token.AccessToken,
|
AccessToken: token.AccessToken,
|
||||||
@@ -72,15 +70,11 @@ func (p *Github) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
|
|
||||||
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
||||||
|
|
||||||
// in case user has set "Keep my email address private", send an
|
|
||||||
// **optional** API request to retrieve the verified primary email
|
|
||||||
if user.Email == "" {
|
|
||||||
email, err := p.fetchPrimaryEmail(token)
|
email, err := p.fetchPrimaryEmail(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user.Email = email
|
user.Email = email
|
||||||
}
|
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
@@ -34,7 +35,7 @@ func NewGitlabProvider() *Gitlab {
|
|||||||
|
|
||||||
// FetchAuthUser returns an AuthUser instance based the Gitlab's user api.
|
// FetchAuthUser returns an AuthUser instance based the Gitlab's user api.
|
||||||
//
|
//
|
||||||
// API reference: https://docs.gitlab.com/ee/api/users.html#for-admin
|
// API reference: https://docs.gitlab.com/api/users/#retrieve-the-current-user
|
||||||
func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||||
data, err := p.FetchRawUserData(token)
|
data, err := p.FetchRawUserData(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -52,6 +53,7 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
AvatarUrl string `json:"avatar_url"`
|
AvatarUrl string `json:"avatar_url"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -61,7 +63,6 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
Id: strconv.Itoa(extracted.Id),
|
Id: strconv.Itoa(extracted.Id),
|
||||||
Name: extracted.Name,
|
Name: extracted.Name,
|
||||||
Username: extracted.Username,
|
Username: extracted.Username,
|
||||||
Email: extracted.Email,
|
|
||||||
AvatarUrl: extracted.AvatarUrl,
|
AvatarUrl: extracted.AvatarUrl,
|
||||||
RawUser: rawUser,
|
RawUser: rawUser,
|
||||||
AccessToken: token.AccessToken,
|
AccessToken: token.AccessToken,
|
||||||
@@ -70,5 +71,10 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
|
|
||||||
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
||||||
|
|
||||||
|
confirmedAt, err := time.Parse(time.RFC3339, extracted.ConfirmedAt)
|
||||||
|
if err == nil && !confirmedAt.IsZero() {
|
||||||
|
user.Email = extracted.Email
|
||||||
|
}
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
+3
-2
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
|
"github.com/spf13/cast"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ func (p *OIDC) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
Username string `json:"preferred_username"`
|
Username string `json:"preferred_username"`
|
||||||
Picture string `json:"picture"`
|
Picture string `json:"picture"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
EmailVerified bool `json:"email_verified"`
|
EmailVerified any `json:"email_verified"` // see #6657
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -70,7 +71,7 @@ func (p *OIDC) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
|||||||
|
|
||||||
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
user.Expiry, _ = types.ParseDateTime(token.Expiry)
|
||||||
|
|
||||||
if extracted.EmailVerified {
|
if cast.ToBool(extracted.EmailVerified) {
|
||||||
user.Email = extracted.Email
|
user.Email = extracted.Email
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -13,6 +13,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
)
|
)
|
||||||
|
|
||||||
type job struct {
|
type job struct {
|
||||||
@@ -170,7 +172,7 @@ func (c *Cron) Start() {
|
|||||||
c.runDue(time.Now())
|
c.runDue(time.Now())
|
||||||
|
|
||||||
// run after each tick
|
// run after each tick
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-c.tickerDone:
|
case <-c.tickerDone:
|
||||||
@@ -179,7 +181,7 @@ func (c *Cron) Start() {
|
|||||||
c.runDue(t)
|
c.runDue(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
})
|
})
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
}
|
}
|
||||||
@@ -201,7 +203,7 @@ func (c *Cron) runDue(t time.Time) {
|
|||||||
|
|
||||||
for _, j := range c.jobs {
|
for _, j := range c.jobs {
|
||||||
if j.schedule.IsDue(moment) {
|
if j.schedule.IsDue(moment) {
|
||||||
go j.run()
|
routine.FireAndForget(j.run)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/gabriel-vasile/mimetype"
|
"github.com/gabriel-vasile/mimetype"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/filesystem/internal/s3lite"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
"gocloud.dev/blob"
|
"gocloud.dev/blob"
|
||||||
"gocloud.dev/blob/fileblob"
|
"gocloud.dev/blob/fileblob"
|
||||||
@@ -47,25 +48,23 @@ func NewS3(
|
|||||||
|
|
||||||
cred := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")
|
cred := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")
|
||||||
|
|
||||||
cfg, err := config.LoadDefaultConfig(ctx,
|
cfg, err := config.LoadDefaultConfig(
|
||||||
|
ctx,
|
||||||
config.WithCredentialsProvider(cred),
|
config.WithCredentialsProvider(cred),
|
||||||
config.WithRegion(region),
|
config.WithRegion(region),
|
||||||
config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
|
||||||
// ensure that the endpoint has url scheme for
|
|
||||||
// backward compatibility with v1 of the aws sdk
|
|
||||||
prefixedEndpoint := endpoint
|
|
||||||
if !strings.Contains(endpoint, "://") {
|
|
||||||
prefixedEndpoint = "https://" + endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
return aws.Endpoint{URL: prefixedEndpoint, SigningRegion: region}, nil
|
|
||||||
})),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
|
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
|
||||||
|
// ensure that the endpoint has url scheme for
|
||||||
|
// backward compatibility with v1 of the aws sdk
|
||||||
|
if !strings.Contains(endpoint, "://") {
|
||||||
|
endpoint = "https://" + endpoint
|
||||||
|
}
|
||||||
|
o.BaseEndpoint = aws.String(endpoint)
|
||||||
|
|
||||||
o.UsePathStyle = s3ForcePathStyle
|
o.UsePathStyle = s3ForcePathStyle
|
||||||
|
|
||||||
// Google Cloud Storage alters the Accept-Encoding header,
|
// Google Cloud Storage alters the Accept-Encoding header,
|
||||||
@@ -76,7 +75,7 @@ func NewS3(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
bucket, err := OpenBucketV2(ctx, client, bucketName, nil)
|
bucket, err := s3lite.OpenBucketV2(ctx, client, bucketName, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -345,6 +344,26 @@ func (s *System) DeletePrefix(prefix string) []error {
|
|||||||
return failed
|
return failed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the provided dir prefix doesn't have any files.
|
||||||
|
//
|
||||||
|
// A trailing slash will be appended to a non-empty dir string argument
|
||||||
|
// to ensure that the checked prefix is a "directory".
|
||||||
|
//
|
||||||
|
// Returns "false" in case the has at least one file, otherwise - "true".
|
||||||
|
func (s *System) IsEmptyDir(dir string) bool {
|
||||||
|
if dir != "" && !strings.HasSuffix(dir, "/") {
|
||||||
|
dir += "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
iter := s.bucket.List(&blob.ListOptions{
|
||||||
|
Prefix: dir,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := iter.Next(s.ctx)
|
||||||
|
|
||||||
|
return err == io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
var inlineServeContentTypes = []string{
|
var inlineServeContentTypes = []string{
|
||||||
// image
|
// image
|
||||||
"image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp", "image/x-icon", "image/bmp",
|
"image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp", "image/x-icon", "image/bmp",
|
||||||
|
|||||||
@@ -169,6 +169,41 @@ func TestFileSystemDeletePrefixWithTrailingSlash(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFileSystemIsEmptyDir(t *testing.T) {
|
||||||
|
dir := createTestDir(t)
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
fsys, err := filesystem.NewLocal(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer fsys.Close()
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
dir string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{"", false}, // special case that shouldn't be suffixed with delimiter to search for any files within the bucket
|
||||||
|
{"/", true},
|
||||||
|
{"missing", true},
|
||||||
|
{"missing/", true},
|
||||||
|
{"test", false},
|
||||||
|
{"test/", false},
|
||||||
|
{"empty", true},
|
||||||
|
{"empty/", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
t.Run(s.dir, func(t *testing.T) {
|
||||||
|
result := fsys.IsEmptyDir(s.dir)
|
||||||
|
|
||||||
|
if result != s.expected {
|
||||||
|
t.Fatalf("Expected %v, got %v", s.expected, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFileSystemUploadMultipart(t *testing.T) {
|
func TestFileSystemUploadMultipart(t *testing.T) {
|
||||||
dir := createTestDir(t)
|
dir := createTestDir(t)
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
// (V1) *s3.PutObjectInput; (V2) *s3v2.PutObjectInput, when Options.Method == http.MethodPut, or
|
// (V1) *s3.PutObjectInput; (V2) *s3v2.PutObjectInput, when Options.Method == http.MethodPut, or
|
||||||
// (V1) *s3.DeleteObjectInput; (V2) [not supported] when Options.Method == http.MethodDelete
|
// (V1) *s3.DeleteObjectInput; (V2) [not supported] when Options.Method == http.MethodDelete
|
||||||
|
|
||||||
package filesystem
|
package s3lite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -82,10 +82,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
|
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
|
||||||
awsv2cfg "github.com/aws/aws-sdk-go-v2/config"
|
|
||||||
s3managerv2 "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
s3managerv2 "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||||
s3v2 "github.com/aws/aws-sdk-go-v2/service/s3"
|
s3v2 "github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
typesv2 "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
typesv2 "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
|
|
||||||
"github.com/aws/smithy-go"
|
"github.com/aws/smithy-go"
|
||||||
"gocloud.dev/blob"
|
"gocloud.dev/blob"
|
||||||
@@ -244,116 +244,8 @@ func URLUnescape(s string) string {
|
|||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
// UseV2 returns true iff the URL parameters indicate that the provider
|
|
||||||
// should use the AWS SDK v2.
|
|
||||||
//
|
|
||||||
// "awssdk=v1" will force V1.
|
|
||||||
// "awssdk=v2" will force V2.
|
|
||||||
// No "awssdk" parameter (or any other value) will return the default, currently V1.
|
|
||||||
// Note that the default may change in the future.
|
|
||||||
func UseV2(q url.Values) bool {
|
|
||||||
if values, ok := q["awssdk"]; ok {
|
|
||||||
if values[0] == "v2" || values[0] == "V2" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDefaultV2Config returns a aws.Config for AWS SDK v2, using the default options.
|
|
||||||
func NewDefaultV2Config(ctx context.Context) (awsv2.Config, error) {
|
|
||||||
return awsv2cfg.LoadDefaultConfig(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// V2ConfigFromURLParams returns an aws.Config for AWS SDK v2 initialized based on the URL
|
|
||||||
// parameters in q. It is intended to be used by URLOpeners for AWS services if
|
|
||||||
// UseV2 returns true.
|
|
||||||
//
|
|
||||||
// https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config
|
|
||||||
//
|
|
||||||
// It returns an error if q contains any unknown query parameters; callers
|
|
||||||
// should remove any query parameters they know about from q before calling
|
|
||||||
// V2ConfigFromURLParams.
|
|
||||||
//
|
|
||||||
// The following query options are supported:
|
|
||||||
// - region: The AWS region for requests; sets WithRegion.
|
|
||||||
// - profile: The shared config profile to use; sets SharedConfigProfile.
|
|
||||||
// - endpoint: The AWS service endpoint to send HTTP request.
|
|
||||||
func V2ConfigFromURLParams(ctx context.Context, q url.Values) (awsv2.Config, error) {
|
|
||||||
var opts []func(*awsv2cfg.LoadOptions) error
|
|
||||||
for param, values := range q {
|
|
||||||
value := values[0]
|
|
||||||
switch param {
|
|
||||||
case "region":
|
|
||||||
opts = append(opts, awsv2cfg.WithRegion(value))
|
|
||||||
case "endpoint":
|
|
||||||
customResolver := awsv2.EndpointResolverWithOptionsFunc(
|
|
||||||
func(service, region string, options ...interface{}) (awsv2.Endpoint, error) {
|
|
||||||
return awsv2.Endpoint{
|
|
||||||
PartitionID: "aws",
|
|
||||||
URL: value,
|
|
||||||
SigningRegion: region,
|
|
||||||
}, nil
|
|
||||||
})
|
|
||||||
opts = append(opts, awsv2cfg.WithEndpointResolverWithOptions(customResolver))
|
|
||||||
case "profile":
|
|
||||||
opts = append(opts, awsv2cfg.WithSharedConfigProfile(value))
|
|
||||||
case "awssdk":
|
|
||||||
// ignore, should be handled before this
|
|
||||||
default:
|
|
||||||
return awsv2.Config{}, fmt.Errorf("unknown query parameter %q", param)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return awsv2cfg.LoadDefaultConfig(ctx, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
|
|
||||||
const defaultPageSize = 1000
|
const defaultPageSize = 1000
|
||||||
|
|
||||||
func init() {
|
|
||||||
blob.DefaultURLMux().RegisterBucket(Scheme, new(urlSessionOpener))
|
|
||||||
}
|
|
||||||
|
|
||||||
type urlSessionOpener struct{}
|
|
||||||
|
|
||||||
func (o *urlSessionOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) {
|
|
||||||
opener := &URLOpener{UseV2: true}
|
|
||||||
return opener.OpenBucketURL(ctx, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scheme is the URL scheme s3blob registers its URLOpener under on
|
|
||||||
// blob.DefaultMux.
|
|
||||||
const Scheme = "s3"
|
|
||||||
|
|
||||||
// URLOpener opens S3 URLs like "s3://mybucket".
|
|
||||||
//
|
|
||||||
// The URL host is used as the bucket name.
|
|
||||||
//
|
|
||||||
// Use "awssdk=v1" to force using AWS SDK v1, "awssdk=v2" to force using AWS SDK v2,
|
|
||||||
// or anything else to accept the default.
|
|
||||||
//
|
|
||||||
// For V1, see gocloud.dev/aws/ConfigFromURLParams for supported query parameters
|
|
||||||
// for overriding the aws.Session from the URL.
|
|
||||||
// For V2, see gocloud.dev/aws/V2ConfigFromURLParams.
|
|
||||||
type URLOpener struct {
|
|
||||||
// UseV2 indicates whether the AWS SDK V2 should be used.
|
|
||||||
UseV2 bool
|
|
||||||
|
|
||||||
// Options specifies the options to pass to OpenBucket.
|
|
||||||
Options Options
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenBucketURL opens a blob.Bucket based on u.
|
|
||||||
func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) {
|
|
||||||
cfg, err := V2ConfigFromURLParams(ctx, u.Query())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("open bucket %v: %v", u, err)
|
|
||||||
}
|
|
||||||
clientV2 := s3v2.NewFromConfig(cfg)
|
|
||||||
return OpenBucketV2(ctx, clientV2, u.Host, &o.Options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options sets options for constructing a *blob.Bucket backed by fileblob.
|
// Options sets options for constructing a *blob.Bucket backed by fileblob.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// UseLegacyList forces the use of ListObjects instead of ListObjectsV2.
|
// UseLegacyList forces the use of ListObjects instead of ListObjectsV2.
|
||||||
@@ -471,7 +363,7 @@ func (w *writer) Upload(r io.Reader) error {
|
|||||||
// error uploading to S3.
|
// error uploading to S3.
|
||||||
func (w *writer) open(r io.Reader, closePipeOnError bool) {
|
func (w *writer) open(r io.Reader, closePipeOnError bool) {
|
||||||
// This goroutine will keep running until Close, unless there's an error.
|
// This goroutine will keep running until Close, unless there's an error.
|
||||||
go func() {
|
routine.FireAndForget(func() {
|
||||||
defer close(w.donec)
|
defer close(w.donec)
|
||||||
|
|
||||||
if r == nil {
|
if r == nil {
|
||||||
@@ -488,7 +380,7 @@ func (w *writer) open(r io.Reader, closePipeOnError bool) {
|
|||||||
}
|
}
|
||||||
w.err = err
|
w.err = err
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close completes the writer and closes it. Any error occurring during write
|
// Close completes the writer and closes it. Any error occurring during write
|
||||||
@@ -676,64 +568,6 @@ func (b *bucket) listObjectsV2(ctx context.Context, in *s3v2.ListObjectsV2Input,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (b *bucket) listObjects(ctx context.Context, in *s3.ListObjectsV2Input, opts *driver.ListOptions) (*s3.ListObjectsV2Output, error) {
|
|
||||||
// if !b.useLegacyList {
|
|
||||||
// if opts.BeforeList != nil {
|
|
||||||
// asFunc := func(i interface{}) bool {
|
|
||||||
// if p, ok := i.(**s3.ListObjectsV2Input); ok {
|
|
||||||
// *p = in
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// if err := opts.BeforeList(asFunc); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return b.client.ListObjectsV2WithContext(ctx, in)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Use the legacy ListObjects request.
|
|
||||||
// legacyIn := &s3.ListObjectsInput{
|
|
||||||
// Bucket: in.Bucket,
|
|
||||||
// Delimiter: in.Delimiter,
|
|
||||||
// EncodingType: in.EncodingType,
|
|
||||||
// Marker: in.ContinuationToken,
|
|
||||||
// MaxKeys: in.MaxKeys,
|
|
||||||
// Prefix: in.Prefix,
|
|
||||||
// RequestPayer: in.RequestPayer,
|
|
||||||
// }
|
|
||||||
// if opts.BeforeList != nil {
|
|
||||||
// asFunc := func(i interface{}) bool {
|
|
||||||
// p, ok := i.(**s3.ListObjectsInput)
|
|
||||||
// if !ok {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// *p = legacyIn
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if err := opts.BeforeList(asFunc); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// legacyResp, err := b.client.ListObjectsWithContext(ctx, legacyIn)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var nextContinuationToken *string
|
|
||||||
// if legacyResp.NextMarker != nil {
|
|
||||||
// nextContinuationToken = legacyResp.NextMarker
|
|
||||||
// } else if awsv2.ToBool(legacyResp.IsTruncated) {
|
|
||||||
// nextContinuationToken = awsv2.String(awsv2.ToString(legacyResp.Contents[len(legacyResp.Contents)-1].Key))
|
|
||||||
// }
|
|
||||||
// return &s3.ListObjectsV2Output{
|
|
||||||
// CommonPrefixes: legacyResp.CommonPrefixes,
|
|
||||||
// Contents: legacyResp.Contents,
|
|
||||||
// NextContinuationToken: nextContinuationToken,
|
|
||||||
// }, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// As implements driver.As.
|
// As implements driver.As.
|
||||||
func (b *bucket) As(i interface{}) bool {
|
func (b *bucket) As(i interface{}) bool {
|
||||||
p, ok := i.(**s3v2.Client)
|
p, ok := i.(**s3v2.Client)
|
||||||
@@ -2,9 +2,12 @@ package logger
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -251,14 +254,73 @@ func (h *BatchHandler) resolveAttr(data map[string]any, attr slog.Attr) error {
|
|||||||
data[attr.Key] = groupData
|
data[attr.Key] = groupData
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
v := attr.Value.Any()
|
data[attr.Key] = normalizeLogAttrValue(attr.Value.Any())
|
||||||
|
|
||||||
if err, ok := v.(error); ok {
|
|
||||||
data[attr.Key] = err.Error()
|
|
||||||
} else {
|
|
||||||
data[attr.Key] = v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeLogAttrValue(rawAttrValue any) any {
|
||||||
|
switch attrV := rawAttrValue.(type) {
|
||||||
|
case validation.Errors:
|
||||||
|
out := make(map[string]any, len(attrV))
|
||||||
|
for k, v := range attrV {
|
||||||
|
out[k] = serializeLogError(v)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
case map[string]validation.Error:
|
||||||
|
out := make(map[string]any, len(attrV))
|
||||||
|
for k, v := range attrV {
|
||||||
|
out[k] = serializeLogError(v)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
case map[string]error:
|
||||||
|
out := make(map[string]any, len(attrV))
|
||||||
|
for k, v := range attrV {
|
||||||
|
out[k] = serializeLogError(v)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
case map[string]any:
|
||||||
|
out := make(map[string]any, len(attrV))
|
||||||
|
for k, v := range attrV {
|
||||||
|
switch vv := v.(type) {
|
||||||
|
case error:
|
||||||
|
out[k] = serializeLogError(vv)
|
||||||
|
default:
|
||||||
|
out[k] = normalizeLogAttrValue(vv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
case error:
|
||||||
|
// check for wrapped validation.Errors
|
||||||
|
var ve validation.Errors
|
||||||
|
if errors.As(attrV, &ve) {
|
||||||
|
out := make(map[string]any, len(ve))
|
||||||
|
for k, v := range ve {
|
||||||
|
out[k] = serializeLogError(v)
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"data": out,
|
||||||
|
"raw": serializeLogError(attrV),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serializeLogError(attrV)
|
||||||
|
default:
|
||||||
|
return attrV
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeLogError(err error) any {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// prioritize a json structured format (e.g. validation.Errors)
|
||||||
|
jsonErr, ok := err.(json.Marshaler)
|
||||||
|
if ok {
|
||||||
|
return jsonErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to its original string representation
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
validation "github.com/pocketbase/ozzo-validation/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewBatchHandlerPanic(t *testing.T) {
|
func TestNewBatchHandlerPanic(t *testing.T) {
|
||||||
@@ -283,14 +285,45 @@ func TestBatchHandlerAttrsFormat(t *testing.T) {
|
|||||||
h1.Handle(ctx, record)
|
h1.Handle(ctx, record)
|
||||||
h2.Handle(ctx, record)
|
h2.Handle(ctx, record)
|
||||||
|
|
||||||
|
// errors serialization checks
|
||||||
|
errorsRecord := slog.NewRecord(time.Now(), slog.LevelError, "details", 0)
|
||||||
|
errorsRecord.Add("validation.Errors", validation.Errors{
|
||||||
|
"a": validation.NewError("validation_code", "validation_message"),
|
||||||
|
"b": errors.New("plain"),
|
||||||
|
})
|
||||||
|
errorsRecord.Add("wrapped_validation.Errors", fmt.Errorf("wrapped: %w", validation.Errors{
|
||||||
|
"a": validation.NewError("validation_code", "validation_message"),
|
||||||
|
"b": errors.New("plain"),
|
||||||
|
}))
|
||||||
|
errorsRecord.Add("map[string]any", map[string]any{
|
||||||
|
"a": validation.NewError("validation_code", "validation_message"),
|
||||||
|
"b": errors.New("plain"),
|
||||||
|
"c": "test_any",
|
||||||
|
"d": map[string]any{
|
||||||
|
"nestedA": validation.NewError("nested_code", "nested_message"),
|
||||||
|
"nestedB": errors.New("nested_plain"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
errorsRecord.Add("map[string]error", map[string]error{
|
||||||
|
"a": validation.NewError("validation_code", "validation_message"),
|
||||||
|
"b": errors.New("plain"),
|
||||||
|
})
|
||||||
|
errorsRecord.Add("map[string]validation.Error", map[string]validation.Error{
|
||||||
|
"a": validation.NewError("validation_code", "validation_message"),
|
||||||
|
"b": nil,
|
||||||
|
})
|
||||||
|
errorsRecord.Add("plain_error", errors.New("plain"))
|
||||||
|
h0.Handle(ctx, errorsRecord)
|
||||||
|
|
||||||
expected := []string{
|
expected := []string{
|
||||||
`{"name":"test"}`,
|
`{"name":"test"}`,
|
||||||
`{"a":1,"b":"123","name":"test"}`,
|
`{"a":1,"b":"123","name":"test"}`,
|
||||||
`{"a":1,"b":"123","sub":{"c":3,"d":{"d.1":1},"e":"example error","name":"test"}}`,
|
`{"a":1,"b":"123","sub":{"c":3,"d":{"d.1":1},"e":"example error","name":"test"}}`,
|
||||||
|
`{"map[string]any":{"a":"validation_message","b":"plain","c":"test_any","d":{"nestedA":"nested_message","nestedB":"nested_plain"}},"map[string]error":{"a":"validation_message","b":"plain"},"map[string]validation.Error":{"a":"validation_message","b":null},"plain_error":"plain","validation.Errors":{"a":"validation_message","b":"plain"},"wrapped_validation.Errors":{"data":{"a":"validation_message","b":"plain"},"raw":"wrapped: a: validation_message; b: plain."}}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(beforeLogs) != len(expected) {
|
if len(beforeLogs) != len(expected) {
|
||||||
t.Fatalf("Expected %d logs, got %d", len(beforeLogs), len(expected))
|
t.Fatalf("Expected %d logs, got %d", len(expected), len(beforeLogs))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, data := range expected {
|
for i, data := range expected {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func newExcerptModifier(args ...string) (*excerptModifier, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
max := cast.ToInt(args[0])
|
max := cast.ToInt(args[0])
|
||||||
if max == 0 {
|
if max <= 0 {
|
||||||
return nil, errors.New("max argument must be > 0")
|
return nil, errors.New("max argument must be > 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ func TestNewExcerptModifier(t *testing.T) {
|
|||||||
[]string{"something"}, // should fallback to 0 which is not allowed
|
[]string{"something"}, // should fallback to 0 which is not allowed
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"negative numeric max argument",
|
||||||
|
[]string{"-1"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"zero numeric max argument",
|
||||||
|
[]string{"0"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"numeric max argument",
|
"numeric max argument",
|
||||||
[]string{"12"},
|
[]string{"12"},
|
||||||
|
|||||||
@@ -54,14 +54,6 @@ func TestSerialize(t *testing.T) {
|
|||||||
"fields=missing",
|
"fields=missing",
|
||||||
`{"a":1,"b":2,"c":"test"}`,
|
`{"a":1,"b":2,"c":"test"}`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"<200 response",
|
|
||||||
rest.Serializer{},
|
|
||||||
199,
|
|
||||||
map[string]any{"a": 1, "b": 2, "c": "test"},
|
|
||||||
"fields=missing",
|
|
||||||
`{"a":1,"b":2,"c":"test"}`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"non map response",
|
"non map response",
|
||||||
rest.Serializer{},
|
rest.Serializer{},
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/spf13/cast"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MultipartJsonKey is the key for the special multipart/form-data
|
// MultipartJsonKey is the key for the special multipart/form-data
|
||||||
@@ -144,11 +145,15 @@ func bindFormData(c echo.Context, i any) error {
|
|||||||
return echo.BindBody(c, i)
|
return echo.BindBody(c, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inferNumberCharsRegex = regexp.MustCompile(`^[\-\.\d]+$`)
|
||||||
|
|
||||||
// In order to support more seamlessly both json and multipart/form-data requests,
|
// In order to support more seamlessly both json and multipart/form-data requests,
|
||||||
// the following normalization rules are applied for plain multipart string values:
|
// the following normalization rules are applied for plain multipart string values:
|
||||||
// - "true" is converted to the json `true`
|
// - "true" is converted to the json "true"
|
||||||
// - "false" is converted to the json `false`
|
// - "false" is converted to the json "false"
|
||||||
// - numeric (non-scientific) strings are converted to json number
|
// - numeric strings are converted to json number ONLY if the resulted
|
||||||
|
// minimal number string representation is the same as the provided raw string
|
||||||
|
// (aka. scientific notations, "Infinity", "0.0", "0001", etc. are kept as string)
|
||||||
// - any other string (empty string too) is left as it is
|
// - any other string (empty string too) is left as it is
|
||||||
func normalizeMultipartValue(raw string) any {
|
func normalizeMultipartValue(raw string) any {
|
||||||
switch raw {
|
switch raw {
|
||||||
@@ -159,8 +164,12 @@ func normalizeMultipartValue(raw string) any {
|
|||||||
case "false":
|
case "false":
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
if raw[0] == '-' || (raw[0] >= '0' && raw[0] <= '9') {
|
// try to convert to number
|
||||||
if v, err := cast.ToFloat64E(raw); err == nil {
|
//
|
||||||
|
// note: expects the provided raw string to match exactly with the minimal string representation of the parsed float
|
||||||
|
if raw[0] == '-' || (raw[0] >= '0' && raw[0] <= '9') && inferNumberCharsRegex.Match([]byte(raw)) {
|
||||||
|
v, err := strconv.ParseFloat(raw, 64)
|
||||||
|
if err == nil && strconv.FormatFloat(v, 'f', -1, 64) == raw {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package routine
|
package routine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -30,3 +31,17 @@ func FireAndForget(f func(), wg ...*sync.WaitGroup) {
|
|||||||
f()
|
f()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SafeWrap wraps the provided function with auto panic recover handling
|
||||||
|
// and returns any eventual panic as regular error.
|
||||||
|
func SafeWrap(f func() error) func() error {
|
||||||
|
return func() (err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = fmt.Errorf("[SafeWrap] recovered from panic: %v", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package routine_test
|
package routine_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@ func TestFireAndForget(t *testing.T) {
|
|||||||
|
|
||||||
fn := func() {
|
fn := func() {
|
||||||
called = true
|
called = true
|
||||||
panic("test")
|
panic("test_recover")
|
||||||
}
|
}
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
@@ -22,6 +24,56 @@ func TestFireAndForget(t *testing.T) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if !called {
|
if !called {
|
||||||
t.Error("Expected fn to be called.")
|
t.Fatal("Expected fn to be called.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSafeWrap(t *testing.T) {
|
||||||
|
t.Run("panic", func(t *testing.T) {
|
||||||
|
called := false
|
||||||
|
|
||||||
|
fn := func() error {
|
||||||
|
called = true
|
||||||
|
panic("test_recover")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := routine.SafeWrap(fn)()
|
||||||
|
|
||||||
|
if !called {
|
||||||
|
t.Fatal("Expected fn to be called.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected fn panic to be converted to error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(err.Error(), "test_recover") {
|
||||||
|
t.Fatal("Expected the returned error to contain the recovered panic value")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("regular error", func(t *testing.T) {
|
||||||
|
called := false
|
||||||
|
|
||||||
|
fn := func() error {
|
||||||
|
called = true
|
||||||
|
return errors.New("test_error")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := routine.SafeWrap(fn)()
|
||||||
|
|
||||||
|
if !called {
|
||||||
|
t.Fatal("Expected fn to be called.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected to return the wrapped fn error")
|
||||||
|
}
|
||||||
|
|
||||||
|
errStr := err.Error()
|
||||||
|
expected := "test_error"
|
||||||
|
if errStr != expected {
|
||||||
|
t.Fatalf("Expected %s error, got %s", expected, errStr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/routine"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -268,8 +269,8 @@ func (s *Provider) Exec(items any) (*Result, error) {
|
|||||||
// execute the 2 queries concurrently
|
// execute the 2 queries concurrently
|
||||||
errg := new(errgroup.Group)
|
errg := new(errgroup.Group)
|
||||||
errg.SetLimit(2)
|
errg.SetLimit(2)
|
||||||
errg.Go(countExec)
|
errg.Go(routine.SafeWrap(countExec))
|
||||||
errg.Go(modelsExec)
|
errg.Go(routine.SafeWrap(modelsExec))
|
||||||
if err := errg.Wait(); err != nil {
|
if err := errg.Wait(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ PB_DOCS_URL = "https://pocketbase.io/docs/"
|
|||||||
PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk"
|
PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk"
|
||||||
PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk"
|
PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk"
|
||||||
PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases"
|
PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases"
|
||||||
PB_VERSION = "v0.22.21"
|
PB_VERSION = "v0.22.48"
|
||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
import{S as Se,i as ye,s as Ae,O as G,e as c,v as w,b as k,c as se,f as p,g as d,h as a,m as ae,w as U,P as ve,Q as Te,k as je,R as Be,n as Oe,t as W,a as V,o as u,d as ne,C as Fe,A as Qe,q as L,r as Ne,N as qe}from"./index-Bp3jGQ0J.js";import{S as He}from"./SdkTabs-DxNNd6Sw.js";import{F as Ke}from"./FieldsQueryParam-zDO3HzQv.js";function Ce(n,l,o){const s=n.slice();return s[5]=l[o],s}function Pe(n,l,o){const s=n.slice();return s[5]=l[o],s}function $e(n,l){let o,s=l[5].code+"",_,f,i,h;function m(){return l[4](l[5])}return{key:n,first:null,c(){o=c("button"),_=w(s),f=k(),p(o,"class","tab-item"),L(o,"active",l[1]===l[5].code),this.first=o},m(v,C){d(v,o,C),a(o,_),a(o,f),i||(h=Ne(o,"click",m),i=!0)},p(v,C){l=v,C&4&&s!==(s=l[5].code+"")&&U(_,s),C&6&&L(o,"active",l[1]===l[5].code)},d(v){v&&u(o),i=!1,h()}}}function Me(n,l){let o,s,_,f;return s=new qe({props:{content:l[5].body}}),{key:n,first:null,c(){o=c("div"),se(s.$$.fragment),_=k(),p(o,"class","tab-item"),L(o,"active",l[1]===l[5].code),this.first=o},m(i,h){d(i,o,h),ae(s,o,null),a(o,_),f=!0},p(i,h){l=i;const m={};h&4&&(m.content=l[5].body),s.$set(m),(!f||h&6)&&L(o,"active",l[1]===l[5].code)},i(i){f||(W(s.$$.fragment,i),f=!0)},o(i){V(s.$$.fragment,i),f=!1},d(i){i&&u(o),ne(s)}}}function ze(n){var be,ke;let l,o,s=n[0].name+"",_,f,i,h,m,v,C,q=n[0].name+"",E,ie,I,P,J,T,Y,$,H,ce,K,j,re,R,z=n[0].name+"",X,de,Z,B,x,M,ee,ue,te,A,le,O,oe,S,F,g=[],he=new Map,me,Q,b=[],fe=new Map,y;P=new He({props:{js:`
|
import{S as Se,i as ye,s as Te,O as G,b as d,d as se,t as U,a as W,r as V,Q as ve,R as je,g as Ae,T as Be,e as Oe,f as u,h as a,m as ae,n as c,u as w,k,c as ne,o as p,C as Fe,p as Qe,w as L,x as Ne,N as He}from"./index-CRh7dlL-.js";import{S as Ke}from"./SdkTabs-C6hORRCs.js";import{F as qe}from"./FieldsQueryParam-BKn2QRBU.js";function Ce(n,l,o){const s=n.slice();return s[5]=l[o],s}function Pe(n,l,o){const s=n.slice();return s[5]=l[o],s}function $e(n,l){let o,s=l[5].code+"",_,f,i,h;function m(){return l[4](l[5])}return{key:n,first:null,c(){o=c("button"),_=w(s),f=k(),p(o,"class","tab-item"),L(o,"active",l[1]===l[5].code),this.first=o},m(v,C){u(v,o,C),a(o,_),a(o,f),i||(h=Ne(o,"click",m),i=!0)},p(v,C){l=v,C&4&&s!==(s=l[5].code+"")&&V(_,s),C&6&&L(o,"active",l[1]===l[5].code)},d(v){v&&d(o),i=!1,h()}}}function Me(n,l){let o,s,_,f;return s=new He({props:{content:l[5].body}}),{key:n,first:null,c(){o=c("div"),ne(s.$$.fragment),_=k(),p(o,"class","tab-item"),L(o,"active",l[1]===l[5].code),this.first=o},m(i,h){u(i,o,h),ae(s,o,null),a(o,_),f=!0},p(i,h){l=i;const m={};h&4&&(m.content=l[5].body),s.$set(m),(!f||h&6)&&L(o,"active",l[1]===l[5].code)},i(i){f||(W(s.$$.fragment,i),f=!0)},o(i){U(s.$$.fragment,i),f=!1},d(i){i&&d(o),se(s)}}}function ze(n){var be,ke;let l,o,s=n[0].name+"",_,f,i,h,m,v,C,H=n[0].name+"",E,ie,I,P,J,j,Y,$,K,ce,q,A,re,R,z=n[0].name+"",X,de,Z,B,x,M,ee,ue,te,T,le,O,oe,S,F,g=[],he=new Map,me,Q,b=[],fe=new Map,y;P=new Ke({props:{js:`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${n[3]}');
|
const pb = new PocketBase('${n[3]}');
|
||||||
@@ -14,7 +14,7 @@ import{S as Se,i as ye,s as Ae,O as G,e as c,v as w,b as k,c as se,f as p,g as d
|
|||||||
...
|
...
|
||||||
|
|
||||||
final result = await pb.collection('${(ke=n[0])==null?void 0:ke.name}').listAuthMethods();
|
final result = await pb.collection('${(ke=n[0])==null?void 0:ke.name}').listAuthMethods();
|
||||||
`}}),A=new Ke({});let D=G(n[2]);const pe=e=>e[5].code;for(let e=0;e<D.length;e+=1){let t=Pe(n,D,e),r=pe(t);he.set(r,g[e]=$e(r,t))}let N=G(n[2]);const _e=e=>e[5].code;for(let e=0;e<N.length;e+=1){let t=Ce(n,N,e),r=_e(t);fe.set(r,b[e]=Me(r,t))}return{c(){l=c("h3"),o=w("List auth methods ("),_=w(s),f=w(")"),i=k(),h=c("div"),m=c("p"),v=w("Returns a public list with all allowed "),C=c("strong"),E=w(q),ie=w(" authentication methods."),I=k(),se(P.$$.fragment),J=k(),T=c("h6"),T.textContent="API details",Y=k(),$=c("div"),H=c("strong"),H.textContent="GET",ce=k(),K=c("div"),j=c("p"),re=w("/api/collections/"),R=c("strong"),X=w(z),de=w("/auth-methods"),Z=k(),B=c("div"),B.textContent="Query parameters",x=k(),M=c("table"),ee=c("thead"),ee.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr>',ue=k(),te=c("tbody"),se(A.$$.fragment),le=k(),O=c("div"),O.textContent="Responses",oe=k(),S=c("div"),F=c("div");for(let e=0;e<g.length;e+=1)g[e].c();me=k(),Q=c("div");for(let e=0;e<b.length;e+=1)b[e].c();p(l,"class","m-b-sm"),p(h,"class","content txt-lg m-b-sm"),p(T,"class","m-b-xs"),p(H,"class","label label-primary"),p(K,"class","content"),p($,"class","alert alert-info"),p(B,"class","section-title"),p(M,"class","table-compact table-border m-b-base"),p(O,"class","section-title"),p(F,"class","tabs-header compact combined left"),p(Q,"class","tabs-content"),p(S,"class","tabs")},m(e,t){d(e,l,t),a(l,o),a(l,_),a(l,f),d(e,i,t),d(e,h,t),a(h,m),a(m,v),a(m,C),a(C,E),a(m,ie),d(e,I,t),ae(P,e,t),d(e,J,t),d(e,T,t),d(e,Y,t),d(e,$,t),a($,H),a($,ce),a($,K),a(K,j),a(j,re),a(j,R),a(R,X),a(j,de),d(e,Z,t),d(e,B,t),d(e,x,t),d(e,M,t),a(M,ee),a(M,ue),a(M,te),ae(A,te,null),d(e,le,t),d(e,O,t),d(e,oe,t),d(e,S,t),a(S,F);for(let r=0;r<g.length;r+=1)g[r]&&g[r].m(F,null);a(S,me),a(S,Q);for(let r=0;r<b.length;r+=1)b[r]&&b[r].m(Q,null);y=!0},p(e,[t]){var ge,we;(!y||t&1)&&s!==(s=e[0].name+"")&&U(_,s),(!y||t&1)&&q!==(q=e[0].name+"")&&U(E,q);const r={};t&9&&(r.js=`
|
`}}),T=new qe({});let D=G(n[2]);const pe=e=>e[5].code;for(let e=0;e<D.length;e+=1){let t=Pe(n,D,e),r=pe(t);he.set(r,g[e]=$e(r,t))}let N=G(n[2]);const _e=e=>e[5].code;for(let e=0;e<N.length;e+=1){let t=Ce(n,N,e),r=_e(t);fe.set(r,b[e]=Me(r,t))}return{c(){l=c("h3"),o=w("List auth methods ("),_=w(s),f=w(")"),i=k(),h=c("div"),m=c("p"),v=w("Returns a public list with all allowed "),C=c("strong"),E=w(H),ie=w(" authentication methods."),I=k(),ne(P.$$.fragment),J=k(),j=c("h6"),j.textContent="API details",Y=k(),$=c("div"),K=c("strong"),K.textContent="GET",ce=k(),q=c("div"),A=c("p"),re=w("/api/collections/"),R=c("strong"),X=w(z),de=w("/auth-methods"),Z=k(),B=c("div"),B.textContent="Query parameters",x=k(),M=c("table"),ee=c("thead"),ee.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr>',ue=k(),te=c("tbody"),ne(T.$$.fragment),le=k(),O=c("div"),O.textContent="Responses",oe=k(),S=c("div"),F=c("div");for(let e=0;e<g.length;e+=1)g[e].c();me=k(),Q=c("div");for(let e=0;e<b.length;e+=1)b[e].c();p(l,"class","m-b-sm"),p(h,"class","content txt-lg m-b-sm"),p(j,"class","m-b-xs"),p(K,"class","label label-primary"),p(q,"class","content"),p($,"class","alert alert-info"),p(B,"class","section-title"),p(M,"class","table-compact table-border m-b-base"),p(O,"class","section-title"),p(F,"class","tabs-header compact combined left"),p(Q,"class","tabs-content"),p(S,"class","tabs")},m(e,t){u(e,l,t),a(l,o),a(l,_),a(l,f),u(e,i,t),u(e,h,t),a(h,m),a(m,v),a(m,C),a(C,E),a(m,ie),u(e,I,t),ae(P,e,t),u(e,J,t),u(e,j,t),u(e,Y,t),u(e,$,t),a($,K),a($,ce),a($,q),a(q,A),a(A,re),a(A,R),a(R,X),a(A,de),u(e,Z,t),u(e,B,t),u(e,x,t),u(e,M,t),a(M,ee),a(M,ue),a(M,te),ae(T,te,null),u(e,le,t),u(e,O,t),u(e,oe,t),u(e,S,t),a(S,F);for(let r=0;r<g.length;r+=1)g[r]&&g[r].m(F,null);a(S,me),a(S,Q);for(let r=0;r<b.length;r+=1)b[r]&&b[r].m(Q,null);y=!0},p(e,[t]){var ge,we;(!y||t&1)&&s!==(s=e[0].name+"")&&V(_,s),(!y||t&1)&&H!==(H=e[0].name+"")&&V(E,H);const r={};t&9&&(r.js=`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${e[3]}');
|
const pb = new PocketBase('${e[3]}');
|
||||||
@@ -30,7 +30,7 @@ import{S as Se,i as ye,s as Ae,O as G,e as c,v as w,b as k,c as se,f as p,g as d
|
|||||||
...
|
...
|
||||||
|
|
||||||
final result = await pb.collection('${(we=e[0])==null?void 0:we.name}').listAuthMethods();
|
final result = await pb.collection('${(we=e[0])==null?void 0:we.name}').listAuthMethods();
|
||||||
`),P.$set(r),(!y||t&1)&&z!==(z=e[0].name+"")&&U(X,z),t&6&&(D=G(e[2]),g=ve(g,t,pe,1,e,D,he,F,Te,$e,null,Pe)),t&6&&(N=G(e[2]),je(),b=ve(b,t,_e,1,e,N,fe,Q,Be,Me,null,Ce),Oe())},i(e){if(!y){W(P.$$.fragment,e),W(A.$$.fragment,e);for(let t=0;t<N.length;t+=1)W(b[t]);y=!0}},o(e){V(P.$$.fragment,e),V(A.$$.fragment,e);for(let t=0;t<b.length;t+=1)V(b[t]);y=!1},d(e){e&&(u(l),u(i),u(h),u(I),u(J),u(T),u(Y),u($),u(Z),u(B),u(x),u(M),u(le),u(O),u(oe),u(S)),ne(P,e),ne(A);for(let t=0;t<g.length;t+=1)g[t].d();for(let t=0;t<b.length;t+=1)b[t].d()}}}function De(n,l,o){let s,{collection:_}=l,f=200,i=[];const h=m=>o(1,f=m.code);return n.$$set=m=>{"collection"in m&&o(0,_=m.collection)},o(3,s=Fe.getApiExampleUrl(Qe.baseUrl)),o(2,i=[{code:200,body:`
|
`),P.$set(r),(!y||t&1)&&z!==(z=e[0].name+"")&&V(X,z),t&6&&(D=G(e[2]),g=ve(g,t,pe,1,e,D,he,F,je,$e,null,Pe)),t&6&&(N=G(e[2]),Ae(),b=ve(b,t,_e,1,e,N,fe,Q,Be,Me,null,Ce),Oe())},i(e){if(!y){W(P.$$.fragment,e),W(T.$$.fragment,e);for(let t=0;t<N.length;t+=1)W(b[t]);y=!0}},o(e){U(P.$$.fragment,e),U(T.$$.fragment,e);for(let t=0;t<b.length;t+=1)U(b[t]);y=!1},d(e){e&&(d(l),d(i),d(h),d(I),d(J),d(j),d(Y),d($),d(Z),d(B),d(x),d(M),d(le),d(O),d(oe),d(S)),se(P,e),se(T);for(let t=0;t<g.length;t+=1)g[t].d();for(let t=0;t<b.length;t+=1)b[t].d()}}}function De(n,l,o){let s,{collection:_}=l,f=200,i=[];const h=m=>o(1,f=m.code);return n.$$set=m=>{"collection"in m&&o(0,_=m.collection)},o(3,s=Fe.getApiExampleUrl(Qe.baseUrl)),o(2,i=[{code:200,body:`
|
||||||
{
|
{
|
||||||
"usernamePassword": true,
|
"usernamePassword": true,
|
||||||
"emailPassword": true,
|
"emailPassword": true,
|
||||||
@@ -61,4 +61,4 @@ import{S as Se,i as ye,s as Ae,O as G,e as c,v as w,b as k,c as se,f as p,g as d
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
`}]),[_,f,i,s,h]}class Ve extends Se{constructor(l){super(),ye(this,l,De,ze,Ae,{collection:0})}}export{Ve as default};
|
`}]),[_,f,i,s,h]}class Ve extends Se{constructor(l){super(),ye(this,l,De,ze,Te,{collection:0})}}export{Ve as default};
|
||||||
+7
-7
@@ -1,4 +1,4 @@
|
|||||||
import{S as je,i as xe,s as Je,N as Ue,O as J,e as s,v as k,b as p,c as K,f as b,g as d,h as o,m as I,w as de,P as Ee,Q as Ke,k as Ie,R as We,n as Ge,t as N,a as V,o as u,d as W,C as Le,A as Xe,q as G,r as Ye}from"./index-Bp3jGQ0J.js";import{S as Ze}from"./SdkTabs-DxNNd6Sw.js";import{F as et}from"./FieldsQueryParam-zDO3HzQv.js";function Ne(r,l,a){const n=r.slice();return n[5]=l[a],n}function Ve(r,l,a){const n=r.slice();return n[5]=l[a],n}function ze(r,l){let a,n=l[5].code+"",m,_,i,h;function g(){return l[4](l[5])}return{key:r,first:null,c(){a=s("button"),m=k(n),_=p(),b(a,"class","tab-item"),G(a,"active",l[1]===l[5].code),this.first=a},m(v,w){d(v,a,w),o(a,m),o(a,_),i||(h=Ye(a,"click",g),i=!0)},p(v,w){l=v,w&4&&n!==(n=l[5].code+"")&&de(m,n),w&6&&G(a,"active",l[1]===l[5].code)},d(v){v&&u(a),i=!1,h()}}}function Qe(r,l){let a,n,m,_;return n=new Ue({props:{content:l[5].body}}),{key:r,first:null,c(){a=s("div"),K(n.$$.fragment),m=p(),b(a,"class","tab-item"),G(a,"active",l[1]===l[5].code),this.first=a},m(i,h){d(i,a,h),I(n,a,null),o(a,m),_=!0},p(i,h){l=i;const g={};h&4&&(g.content=l[5].body),n.$set(g),(!_||h&6)&&G(a,"active",l[1]===l[5].code)},i(i){_||(N(n.$$.fragment,i),_=!0)},o(i){V(n.$$.fragment,i),_=!1},d(i){i&&u(a),W(n)}}}function tt(r){var De,Fe;let l,a,n=r[0].name+"",m,_,i,h,g,v,w,B,X,S,z,ue,Q,M,pe,Y,U=r[0].name+"",Z,he,fe,j,ee,D,te,T,oe,be,F,C,le,me,ae,_e,f,ke,R,ge,ve,$e,se,ye,ne,Se,we,Te,re,Ce,Pe,A,ie,O,ce,P,H,y=[],Re=new Map,Ae,E,$=[],qe=new Map,q;v=new Ze({props:{js:`
|
import{S as Ue,i as je,s as Je,N as Qe,O as J,b as d,d as K,t as N,a as V,r as de,Q as Ee,R as Ke,g as Ie,T as We,e as Ge,f as u,h as o,m as I,n as s,u as k,k as p,c as W,o as b,C as Le,p as Xe,w as G,x as Ye}from"./index-CRh7dlL-.js";import{S as Ze}from"./SdkTabs-C6hORRCs.js";import{F as et}from"./FieldsQueryParam-BKn2QRBU.js";function Ne(r,l,a){const n=r.slice();return n[5]=l[a],n}function Ve(r,l,a){const n=r.slice();return n[5]=l[a],n}function xe(r,l){let a,n=l[5].code+"",m,_,i,h;function g(){return l[4](l[5])}return{key:r,first:null,c(){a=s("button"),m=k(n),_=p(),b(a,"class","tab-item"),G(a,"active",l[1]===l[5].code),this.first=a},m(v,w){u(v,a,w),o(a,m),o(a,_),i||(h=Ye(a,"click",g),i=!0)},p(v,w){l=v,w&4&&n!==(n=l[5].code+"")&&de(m,n),w&6&&G(a,"active",l[1]===l[5].code)},d(v){v&&d(a),i=!1,h()}}}function ze(r,l){let a,n,m,_;return n=new Qe({props:{content:l[5].body}}),{key:r,first:null,c(){a=s("div"),W(n.$$.fragment),m=p(),b(a,"class","tab-item"),G(a,"active",l[1]===l[5].code),this.first=a},m(i,h){u(i,a,h),I(n,a,null),o(a,m),_=!0},p(i,h){l=i;const g={};h&4&&(g.content=l[5].body),n.$set(g),(!_||h&6)&&G(a,"active",l[1]===l[5].code)},i(i){_||(V(n.$$.fragment,i),_=!0)},o(i){N(n.$$.fragment,i),_=!1},d(i){i&&d(a),K(n)}}}function tt(r){var De,Fe;let l,a,n=r[0].name+"",m,_,i,h,g,v,w,M,X,S,x,ue,z,q,pe,Y,Q=r[0].name+"",Z,he,fe,U,ee,D,te,T,oe,be,F,C,le,me,ae,_e,f,ke,P,ge,ve,$e,se,ye,ne,Se,we,Te,re,Ce,Re,A,ie,O,ce,R,H,y=[],Pe=new Map,Ae,E,$=[],Be=new Map,B;v=new Ze({props:{js:`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${r[3]}');
|
const pb = new PocketBase('${r[3]}');
|
||||||
@@ -24,15 +24,15 @@ import{S as je,i as xe,s as Je,N as Ue,O as J,e as s,v as k,b as p,c as K,f as b
|
|||||||
print(pb.authStore.isValid);
|
print(pb.authStore.isValid);
|
||||||
print(pb.authStore.token);
|
print(pb.authStore.token);
|
||||||
print(pb.authStore.model.id);
|
print(pb.authStore.model.id);
|
||||||
`}}),R=new Ue({props:{content:"?expand=relField1,relField2.subRelField"}}),A=new et({props:{prefix:"record."}});let x=J(r[2]);const Be=e=>e[5].code;for(let e=0;e<x.length;e+=1){let t=Ve(r,x,e),c=Be(t);Re.set(c,y[e]=ze(c,t))}let L=J(r[2]);const Me=e=>e[5].code;for(let e=0;e<L.length;e+=1){let t=Ne(r,L,e),c=Me(t);qe.set(c,$[e]=Qe(c,t))}return{c(){l=s("h3"),a=k("Auth refresh ("),m=k(n),_=k(")"),i=p(),h=s("div"),h.innerHTML=`<p>Returns a new auth response (token and record data) for an
|
`}}),P=new Qe({props:{content:"?expand=relField1,relField2.subRelField"}}),A=new et({props:{prefix:"record."}});let j=J(r[2]);const Me=e=>e[5].code;for(let e=0;e<j.length;e+=1){let t=Ve(r,j,e),c=Me(t);Pe.set(c,y[e]=xe(c,t))}let L=J(r[2]);const qe=e=>e[5].code;for(let e=0;e<L.length;e+=1){let t=Ne(r,L,e),c=qe(t);Be.set(c,$[e]=ze(c,t))}return{c(){l=s("h3"),a=k("Auth refresh ("),m=k(n),_=k(")"),i=p(),h=s("div"),h.innerHTML=`<p>Returns a new auth response (token and record data) for an
|
||||||
<strong>already authenticated record</strong>.</p> <p><em>This method is usually called by users on page/screen reload to ensure that the previously stored
|
<strong>already authenticated record</strong>.</p> <p><em>This method is usually called by users on page/screen reload to ensure that the previously stored
|
||||||
data in <code>pb.authStore</code> is still valid and up-to-date.</em></p>`,g=p(),K(v.$$.fragment),w=p(),B=s("h6"),B.textContent="API details",X=p(),S=s("div"),z=s("strong"),z.textContent="POST",ue=p(),Q=s("div"),M=s("p"),pe=k("/api/collections/"),Y=s("strong"),Z=k(U),he=k("/auth-refresh"),fe=p(),j=s("p"),j.innerHTML="Requires record <code>Authorization:TOKEN</code> header",ee=p(),D=s("div"),D.textContent="Query parameters",te=p(),T=s("table"),oe=s("thead"),oe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',be=p(),F=s("tbody"),C=s("tr"),le=s("td"),le.textContent="expand",me=p(),ae=s("td"),ae.innerHTML='<span class="label">String</span>',_e=p(),f=s("td"),ke=k(`Auto expand record relations. Ex.:
|
data in <code>pb.authStore</code> is still valid and up-to-date.</em></p>`,g=p(),W(v.$$.fragment),w=p(),M=s("h6"),M.textContent="API details",X=p(),S=s("div"),x=s("strong"),x.textContent="POST",ue=p(),z=s("div"),q=s("p"),pe=k("/api/collections/"),Y=s("strong"),Z=k(Q),he=k("/auth-refresh"),fe=p(),U=s("p"),U.innerHTML="Requires record <code>Authorization:TOKEN</code> header",ee=p(),D=s("div"),D.textContent="Query parameters",te=p(),T=s("table"),oe=s("thead"),oe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',be=p(),F=s("tbody"),C=s("tr"),le=s("td"),le.textContent="expand",me=p(),ae=s("td"),ae.innerHTML='<span class="label">String</span>',_e=p(),f=s("td"),ke=k(`Auto expand record relations. Ex.:
|
||||||
`),K(R.$$.fragment),ge=k(`
|
`),W(P.$$.fragment),ge=k(`
|
||||||
Supports up to 6-levels depth nested relations expansion. `),ve=s("br"),$e=k(`
|
Supports up to 6-levels depth nested relations expansion. `),ve=s("br"),$e=k(`
|
||||||
The expanded relations will be appended to the record under the
|
The expanded relations will be appended to the record under the
|
||||||
`),se=s("code"),se.textContent="expand",ye=k(" property (eg. "),ne=s("code"),ne.textContent='"expand": {"relField1": {...}, ...}',Se=k(`).
|
`),se=s("code"),se.textContent="expand",ye=k(" property (eg. "),ne=s("code"),ne.textContent='"expand": {"relField1": {...}, ...}',Se=k(`).
|
||||||
`),we=s("br"),Te=k(`
|
`),we=s("br"),Te=k(`
|
||||||
Only the relations to which the request user has permissions to `),re=s("strong"),re.textContent="view",Ce=k(" will be expanded."),Pe=p(),K(A.$$.fragment),ie=p(),O=s("div"),O.textContent="Responses",ce=p(),P=s("div"),H=s("div");for(let e=0;e<y.length;e+=1)y[e].c();Ae=p(),E=s("div");for(let e=0;e<$.length;e+=1)$[e].c();b(l,"class","m-b-sm"),b(h,"class","content txt-lg m-b-sm"),b(B,"class","m-b-xs"),b(z,"class","label label-primary"),b(Q,"class","content"),b(j,"class","txt-hint txt-sm txt-right"),b(S,"class","alert alert-success"),b(D,"class","section-title"),b(T,"class","table-compact table-border m-b-base"),b(O,"class","section-title"),b(H,"class","tabs-header compact combined left"),b(E,"class","tabs-content"),b(P,"class","tabs")},m(e,t){d(e,l,t),o(l,a),o(l,m),o(l,_),d(e,i,t),d(e,h,t),d(e,g,t),I(v,e,t),d(e,w,t),d(e,B,t),d(e,X,t),d(e,S,t),o(S,z),o(S,ue),o(S,Q),o(Q,M),o(M,pe),o(M,Y),o(Y,Z),o(M,he),o(S,fe),o(S,j),d(e,ee,t),d(e,D,t),d(e,te,t),d(e,T,t),o(T,oe),o(T,be),o(T,F),o(F,C),o(C,le),o(C,me),o(C,ae),o(C,_e),o(C,f),o(f,ke),I(R,f,null),o(f,ge),o(f,ve),o(f,$e),o(f,se),o(f,ye),o(f,ne),o(f,Se),o(f,we),o(f,Te),o(f,re),o(f,Ce),o(F,Pe),I(A,F,null),d(e,ie,t),d(e,O,t),d(e,ce,t),d(e,P,t),o(P,H);for(let c=0;c<y.length;c+=1)y[c]&&y[c].m(H,null);o(P,Ae),o(P,E);for(let c=0;c<$.length;c+=1)$[c]&&$[c].m(E,null);q=!0},p(e,[t]){var Oe,He;(!q||t&1)&&n!==(n=e[0].name+"")&&de(m,n);const c={};t&9&&(c.js=`
|
Only the relations to which the request user has permissions to `),re=s("strong"),re.textContent="view",Ce=k(" will be expanded."),Re=p(),W(A.$$.fragment),ie=p(),O=s("div"),O.textContent="Responses",ce=p(),R=s("div"),H=s("div");for(let e=0;e<y.length;e+=1)y[e].c();Ae=p(),E=s("div");for(let e=0;e<$.length;e+=1)$[e].c();b(l,"class","m-b-sm"),b(h,"class","content txt-lg m-b-sm"),b(M,"class","m-b-xs"),b(x,"class","label label-primary"),b(z,"class","content"),b(U,"class","txt-hint txt-sm txt-right"),b(S,"class","alert alert-success"),b(D,"class","section-title"),b(T,"class","table-compact table-border m-b-base"),b(O,"class","section-title"),b(H,"class","tabs-header compact combined left"),b(E,"class","tabs-content"),b(R,"class","tabs")},m(e,t){u(e,l,t),o(l,a),o(l,m),o(l,_),u(e,i,t),u(e,h,t),u(e,g,t),I(v,e,t),u(e,w,t),u(e,M,t),u(e,X,t),u(e,S,t),o(S,x),o(S,ue),o(S,z),o(z,q),o(q,pe),o(q,Y),o(Y,Z),o(q,he),o(S,fe),o(S,U),u(e,ee,t),u(e,D,t),u(e,te,t),u(e,T,t),o(T,oe),o(T,be),o(T,F),o(F,C),o(C,le),o(C,me),o(C,ae),o(C,_e),o(C,f),o(f,ke),I(P,f,null),o(f,ge),o(f,ve),o(f,$e),o(f,se),o(f,ye),o(f,ne),o(f,Se),o(f,we),o(f,Te),o(f,re),o(f,Ce),o(F,Re),I(A,F,null),u(e,ie,t),u(e,O,t),u(e,ce,t),u(e,R,t),o(R,H);for(let c=0;c<y.length;c+=1)y[c]&&y[c].m(H,null);o(R,Ae),o(R,E);for(let c=0;c<$.length;c+=1)$[c]&&$[c].m(E,null);B=!0},p(e,[t]){var Oe,He;(!B||t&1)&&n!==(n=e[0].name+"")&&de(m,n);const c={};t&9&&(c.js=`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${e[3]}');
|
const pb = new PocketBase('${e[3]}');
|
||||||
@@ -58,7 +58,7 @@ import{S as je,i as xe,s as Je,N as Ue,O as J,e as s,v as k,b as p,c as K,f as b
|
|||||||
print(pb.authStore.isValid);
|
print(pb.authStore.isValid);
|
||||||
print(pb.authStore.token);
|
print(pb.authStore.token);
|
||||||
print(pb.authStore.model.id);
|
print(pb.authStore.model.id);
|
||||||
`),v.$set(c),(!q||t&1)&&U!==(U=e[0].name+"")&&de(Z,U),t&6&&(x=J(e[2]),y=Ee(y,t,Be,1,e,x,Re,H,Ke,ze,null,Ve)),t&6&&(L=J(e[2]),Ie(),$=Ee($,t,Me,1,e,L,qe,E,We,Qe,null,Ne),Ge())},i(e){if(!q){N(v.$$.fragment,e),N(R.$$.fragment,e),N(A.$$.fragment,e);for(let t=0;t<L.length;t+=1)N($[t]);q=!0}},o(e){V(v.$$.fragment,e),V(R.$$.fragment,e),V(A.$$.fragment,e);for(let t=0;t<$.length;t+=1)V($[t]);q=!1},d(e){e&&(u(l),u(i),u(h),u(g),u(w),u(B),u(X),u(S),u(ee),u(D),u(te),u(T),u(ie),u(O),u(ce),u(P)),W(v,e),W(R),W(A);for(let t=0;t<y.length;t+=1)y[t].d();for(let t=0;t<$.length;t+=1)$[t].d()}}}function ot(r,l,a){let n,{collection:m}=l,_=200,i=[];const h=g=>a(1,_=g.code);return r.$$set=g=>{"collection"in g&&a(0,m=g.collection)},r.$$.update=()=>{r.$$.dirty&1&&a(2,i=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:Le.dummyCollectionRecord(m)},null,2)},{code:401,body:`
|
`),v.$set(c),(!B||t&1)&&Q!==(Q=e[0].name+"")&&de(Z,Q),t&6&&(j=J(e[2]),y=Ee(y,t,Me,1,e,j,Pe,H,Ke,xe,null,Ve)),t&6&&(L=J(e[2]),Ie(),$=Ee($,t,qe,1,e,L,Be,E,We,ze,null,Ne),Ge())},i(e){if(!B){V(v.$$.fragment,e),V(P.$$.fragment,e),V(A.$$.fragment,e);for(let t=0;t<L.length;t+=1)V($[t]);B=!0}},o(e){N(v.$$.fragment,e),N(P.$$.fragment,e),N(A.$$.fragment,e);for(let t=0;t<$.length;t+=1)N($[t]);B=!1},d(e){e&&(d(l),d(i),d(h),d(g),d(w),d(M),d(X),d(S),d(ee),d(D),d(te),d(T),d(ie),d(O),d(ce),d(R)),K(v,e),K(P),K(A);for(let t=0;t<y.length;t+=1)y[t].d();for(let t=0;t<$.length;t+=1)$[t].d()}}}function ot(r,l,a){let n,{collection:m}=l,_=200,i=[];const h=g=>a(1,_=g.code);return r.$$set=g=>{"collection"in g&&a(0,m=g.collection)},r.$$.update=()=>{r.$$.dirty&1&&a(2,i=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:Le.dummyCollectionRecord(m)},null,2)},{code:401,body:`
|
||||||
{
|
{
|
||||||
"code": 401,
|
"code": 401,
|
||||||
"message": "The request requires valid record authorization token to be set.",
|
"message": "The request requires valid record authorization token to be set.",
|
||||||
@@ -76,4 +76,4 @@ import{S as je,i as xe,s as Je,N as Ue,O as J,e as s,v as k,b as p,c as K,f as b
|
|||||||
"message": "Missing auth record context.",
|
"message": "Missing auth record context.",
|
||||||
"data": {}
|
"data": {}
|
||||||
}
|
}
|
||||||
`}])},a(3,n=Le.getApiExampleUrl(Xe.baseUrl)),[m,_,i,n,h]}class nt extends je{constructor(l){super(),xe(this,l,ot,tt,Je,{collection:0})}}export{nt as default};
|
`}])},a(3,n=Le.getApiExampleUrl(Xe.baseUrl)),[m,_,i,n,h]}class nt extends Ue{constructor(l){super(),je(this,l,ot,tt,Je,{collection:0})}}export{nt as default};
|
||||||
Vendored
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
import{S as Ee,i as Je,s as Ne,N as Le,O as z,e as o,v as k,b as h,c as I,f as p,g as r,h as a,m as K,w as pe,P as Ue,Q as Qe,k as xe,R as ze,n as Ie,t as L,a as E,o as c,d as G,C as Be,A as Ke,q as X,r as Ge}from"./index-Bp3jGQ0J.js";import{S as Xe}from"./SdkTabs-DxNNd6Sw.js";import{F as Ye}from"./FieldsQueryParam-zDO3HzQv.js";function Fe(s,l,n){const i=s.slice();return i[5]=l[n],i}function He(s,l,n){const i=s.slice();return i[5]=l[n],i}function je(s,l){let n,i=l[5].code+"",f,g,d,m;function _(){return l[4](l[5])}return{key:s,first:null,c(){n=o("button"),f=k(i),g=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(v,O){r(v,n,O),a(n,f),a(n,g),d||(m=Ge(n,"click",_),d=!0)},p(v,O){l=v,O&4&&i!==(i=l[5].code+"")&&pe(f,i),O&6&&X(n,"active",l[1]===l[5].code)},d(v){v&&c(n),d=!1,m()}}}function Ve(s,l){let n,i,f,g;return i=new Le({props:{content:l[5].body}}),{key:s,first:null,c(){n=o("div"),I(i.$$.fragment),f=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(d,m){r(d,n,m),K(i,n,null),a(n,f),g=!0},p(d,m){l=d;const _={};m&4&&(_.content=l[5].body),i.$set(_),(!g||m&6)&&X(n,"active",l[1]===l[5].code)},i(d){g||(L(i.$$.fragment,d),g=!0)},o(d){E(i.$$.fragment,d),g=!1},d(d){d&&c(n),G(i)}}}function Ze(s){let l,n,i=s[0].name+"",f,g,d,m,_,v,O,P,Y,A,J,me,N,R,be,Z,Q=s[0].name+"",ee,fe,te,M,ae,W,le,U,ne,S,oe,ge,B,y,se,ke,ie,_e,b,ve,C,we,$e,Oe,re,Ae,ce,Se,ye,Te,de,Ce,qe,q,ue,F,he,T,H,$=[],De=new Map,Pe,j,w=[],Re=new Map,D;v=new Xe({props:{js:`
|
import{S as xe,i as Ee,s as Je,N as Le,O as z,b as r,d as I,t as L,a as x,r as pe,Q as Ue,R as Ne,g as Qe,T as ze,e as Ie,f as c,h as a,m as K,n as o,u as k,k as h,c as G,o as p,C as Be,p as Ke,w as X,x as Ge}from"./index-CRh7dlL-.js";import{S as Xe}from"./SdkTabs-C6hORRCs.js";import{F as Ye}from"./FieldsQueryParam-BKn2QRBU.js";function Fe(s,l,n){const i=s.slice();return i[5]=l[n],i}function He(s,l,n){const i=s.slice();return i[5]=l[n],i}function je(s,l){let n,i=l[5].code+"",f,g,d,b;function _(){return l[4](l[5])}return{key:s,first:null,c(){n=o("button"),f=k(i),g=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(v,O){c(v,n,O),a(n,f),a(n,g),d||(b=Ge(n,"click",_),d=!0)},p(v,O){l=v,O&4&&i!==(i=l[5].code+"")&&pe(f,i),O&6&&X(n,"active",l[1]===l[5].code)},d(v){v&&r(n),d=!1,b()}}}function Ve(s,l){let n,i,f,g;return i=new Le({props:{content:l[5].body}}),{key:s,first:null,c(){n=o("div"),G(i.$$.fragment),f=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(d,b){c(d,n,b),K(i,n,null),a(n,f),g=!0},p(d,b){l=d;const _={};b&4&&(_.content=l[5].body),i.$set(_),(!g||b&6)&&X(n,"active",l[1]===l[5].code)},i(d){g||(x(i.$$.fragment,d),g=!0)},o(d){L(i.$$.fragment,d),g=!1},d(d){d&&r(n),I(i)}}}function Ze(s){let l,n,i=s[0].name+"",f,g,d,b,_,v,O,P,Y,A,E,be,J,R,me,Z,N=s[0].name+"",ee,fe,te,M,ae,W,le,U,ne,S,oe,ge,B,y,se,ke,ie,_e,m,ve,C,we,$e,Oe,re,Ae,ce,Se,ye,Te,de,Ce,qe,q,ue,F,he,T,H,$=[],De=new Map,Pe,j,w=[],Re=new Map,D;v=new Xe({props:{js:`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${s[3]}');
|
const pb = new PocketBase('${s[3]}');
|
||||||
@@ -45,18 +45,18 @@ import{S as Ee,i as Je,s as Ne,N as Le,O as z,e as o,v as k,b as h,c as I,f as p
|
|||||||
|
|
||||||
// "logout" the last authenticated model
|
// "logout" the last authenticated model
|
||||||
pb.authStore.clear();
|
pb.authStore.clear();
|
||||||
`}}),C=new Le({props:{content:"?expand=relField1,relField2.subRelField"}}),q=new Ye({props:{prefix:"record."}});let x=z(s[2]);const Me=e=>e[5].code;for(let e=0;e<x.length;e+=1){let t=He(s,x,e),u=Me(t);De.set(u,$[e]=je(u,t))}let V=z(s[2]);const We=e=>e[5].code;for(let e=0;e<V.length;e+=1){let t=Fe(s,V,e),u=We(t);Re.set(u,w[e]=Ve(u,t))}return{c(){l=o("h3"),n=k("Auth with OAuth2 ("),f=k(i),g=k(")"),d=h(),m=o("div"),m.innerHTML=`<p>Authenticate with an OAuth2 provider and returns a new auth token and record data.</p> <p>For more details please check the
|
`}}),C=new Le({props:{content:"?expand=relField1,relField2.subRelField"}}),q=new Ye({props:{prefix:"record."}});let Q=z(s[2]);const Me=e=>e[5].code;for(let e=0;e<Q.length;e+=1){let t=He(s,Q,e),u=Me(t);De.set(u,$[e]=je(u,t))}let V=z(s[2]);const We=e=>e[5].code;for(let e=0;e<V.length;e+=1){let t=Fe(s,V,e),u=We(t);Re.set(u,w[e]=Ve(u,t))}return{c(){l=o("h3"),n=k("Auth with OAuth2 ("),f=k(i),g=k(")"),d=h(),b=o("div"),b.innerHTML=`<p>Authenticate with an OAuth2 provider and returns a new auth token and record data.</p> <p>For more details please check the
|
||||||
<a href="https://pocketbase.io/docs/authentication/#oauth2-integration" target="_blank" rel="noopener noreferrer">OAuth2 integration documentation
|
<a href="https://pocketbase.io/docs/authentication/#oauth2-integration" target="_blank" rel="noopener noreferrer">OAuth2 integration documentation
|
||||||
</a>.</p>`,_=h(),I(v.$$.fragment),O=h(),P=o("h6"),P.textContent="API details",Y=h(),A=o("div"),J=o("strong"),J.textContent="POST",me=h(),N=o("div"),R=o("p"),be=k("/api/collections/"),Z=o("strong"),ee=k(Q),fe=k("/auth-with-oauth2"),te=h(),M=o("div"),M.textContent="Body Parameters",ae=h(),W=o("table"),W.innerHTML=`<thead><tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr></thead> <tbody><tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>provider</span></div></td> <td><span class="label">String</span></td> <td>The name of the OAuth2 client provider (eg. "google").</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>code</span></div></td> <td><span class="label">String</span></td> <td>The authorization code returned from the initial request.</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>codeVerifier</span></div></td> <td><span class="label">String</span></td> <td>The code verifier sent with the initial request as part of the code_challenge.</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>redirectUrl</span></div></td> <td><span class="label">String</span></td> <td>The redirect url sent with the initial request.</td></tr> <tr><td><div class="inline-flex"><span class="label label-warning">Optional</span> <span>createData</span></div></td> <td><span class="label">Object</span></td> <td><p>Optional data that will be used when creating the auth record on OAuth2 sign-up.</p> <p>The created auth record must comply with the same requirements and validations in the
|
</a>.</p>`,_=h(),G(v.$$.fragment),O=h(),P=o("h6"),P.textContent="API details",Y=h(),A=o("div"),E=o("strong"),E.textContent="POST",be=h(),J=o("div"),R=o("p"),me=k("/api/collections/"),Z=o("strong"),ee=k(N),fe=k("/auth-with-oauth2"),te=h(),M=o("div"),M.textContent="Body Parameters",ae=h(),W=o("table"),W.innerHTML=`<thead><tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr></thead> <tbody><tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>provider</span></div></td> <td><span class="label">String</span></td> <td>The name of the OAuth2 client provider (eg. "google").</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>code</span></div></td> <td><span class="label">String</span></td> <td>The authorization code returned from the initial request.</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>codeVerifier</span></div></td> <td><span class="label">String</span></td> <td>The code verifier sent with the initial request as part of the code_challenge.</td></tr> <tr><td><div class="inline-flex"><span class="label label-success">Required</span> <span>redirectUrl</span></div></td> <td><span class="label">String</span></td> <td>The redirect url sent with the initial request.</td></tr> <tr><td><div class="inline-flex"><span class="label label-warning">Optional</span> <span>createData</span></div></td> <td><span class="label">Object</span></td> <td><p>Optional data that will be used when creating the auth record on OAuth2 sign-up.</p> <p>The created auth record must comply with the same requirements and validations in the
|
||||||
regular <strong>create</strong> action.
|
regular <strong>create</strong> action.
|
||||||
<br/> <em>The data can only be in <code>json</code>, aka. <code>multipart/form-data</code> and files
|
<br/> <em>The data can only be in <code>json</code>, aka. <code>multipart/form-data</code> and files
|
||||||
upload currently are not supported during OAuth2 sign-ups.</em></p></td></tr></tbody>`,le=h(),U=o("div"),U.textContent="Query parameters",ne=h(),S=o("table"),oe=o("thead"),oe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',ge=h(),B=o("tbody"),y=o("tr"),se=o("td"),se.textContent="expand",ke=h(),ie=o("td"),ie.innerHTML='<span class="label">String</span>',_e=h(),b=o("td"),ve=k(`Auto expand record relations. Ex.:
|
upload currently are not supported during OAuth2 sign-ups.</em></p></td></tr></tbody>`,le=h(),U=o("div"),U.textContent="Query parameters",ne=h(),S=o("table"),oe=o("thead"),oe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',ge=h(),B=o("tbody"),y=o("tr"),se=o("td"),se.textContent="expand",ke=h(),ie=o("td"),ie.innerHTML='<span class="label">String</span>',_e=h(),m=o("td"),ve=k(`Auto expand record relations. Ex.:
|
||||||
`),I(C.$$.fragment),we=k(`
|
`),G(C.$$.fragment),we=k(`
|
||||||
Supports up to 6-levels depth nested relations expansion. `),$e=o("br"),Oe=k(`
|
Supports up to 6-levels depth nested relations expansion. `),$e=o("br"),Oe=k(`
|
||||||
The expanded relations will be appended to the record under the
|
The expanded relations will be appended to the record under the
|
||||||
`),re=o("code"),re.textContent="expand",Ae=k(" property (eg. "),ce=o("code"),ce.textContent='"expand": {"relField1": {...}, ...}',Se=k(`).
|
`),re=o("code"),re.textContent="expand",Ae=k(" property (eg. "),ce=o("code"),ce.textContent='"expand": {"relField1": {...}, ...}',Se=k(`).
|
||||||
`),ye=o("br"),Te=k(`
|
`),ye=o("br"),Te=k(`
|
||||||
Only the relations to which the request user has permissions to `),de=o("strong"),de.textContent="view",Ce=k(" will be expanded."),qe=h(),I(q.$$.fragment),ue=h(),F=o("div"),F.textContent="Responses",he=h(),T=o("div"),H=o("div");for(let e=0;e<$.length;e+=1)$[e].c();Pe=h(),j=o("div");for(let e=0;e<w.length;e+=1)w[e].c();p(l,"class","m-b-sm"),p(m,"class","content txt-lg m-b-sm"),p(P,"class","m-b-xs"),p(J,"class","label label-primary"),p(N,"class","content"),p(A,"class","alert alert-success"),p(M,"class","section-title"),p(W,"class","table-compact table-border m-b-base"),p(U,"class","section-title"),p(S,"class","table-compact table-border m-b-base"),p(F,"class","section-title"),p(H,"class","tabs-header compact combined left"),p(j,"class","tabs-content"),p(T,"class","tabs")},m(e,t){r(e,l,t),a(l,n),a(l,f),a(l,g),r(e,d,t),r(e,m,t),r(e,_,t),K(v,e,t),r(e,O,t),r(e,P,t),r(e,Y,t),r(e,A,t),a(A,J),a(A,me),a(A,N),a(N,R),a(R,be),a(R,Z),a(Z,ee),a(R,fe),r(e,te,t),r(e,M,t),r(e,ae,t),r(e,W,t),r(e,le,t),r(e,U,t),r(e,ne,t),r(e,S,t),a(S,oe),a(S,ge),a(S,B),a(B,y),a(y,se),a(y,ke),a(y,ie),a(y,_e),a(y,b),a(b,ve),K(C,b,null),a(b,we),a(b,$e),a(b,Oe),a(b,re),a(b,Ae),a(b,ce),a(b,Se),a(b,ye),a(b,Te),a(b,de),a(b,Ce),a(B,qe),K(q,B,null),r(e,ue,t),r(e,F,t),r(e,he,t),r(e,T,t),a(T,H);for(let u=0;u<$.length;u+=1)$[u]&&$[u].m(H,null);a(T,Pe),a(T,j);for(let u=0;u<w.length;u+=1)w[u]&&w[u].m(j,null);D=!0},p(e,[t]){(!D||t&1)&&i!==(i=e[0].name+"")&&pe(f,i);const u={};t&9&&(u.js=`
|
Only the relations to which the request user has permissions to `),de=o("strong"),de.textContent="view",Ce=k(" will be expanded."),qe=h(),G(q.$$.fragment),ue=h(),F=o("div"),F.textContent="Responses",he=h(),T=o("div"),H=o("div");for(let e=0;e<$.length;e+=1)$[e].c();Pe=h(),j=o("div");for(let e=0;e<w.length;e+=1)w[e].c();p(l,"class","m-b-sm"),p(b,"class","content txt-lg m-b-sm"),p(P,"class","m-b-xs"),p(E,"class","label label-primary"),p(J,"class","content"),p(A,"class","alert alert-success"),p(M,"class","section-title"),p(W,"class","table-compact table-border m-b-base"),p(U,"class","section-title"),p(S,"class","table-compact table-border m-b-base"),p(F,"class","section-title"),p(H,"class","tabs-header compact combined left"),p(j,"class","tabs-content"),p(T,"class","tabs")},m(e,t){c(e,l,t),a(l,n),a(l,f),a(l,g),c(e,d,t),c(e,b,t),c(e,_,t),K(v,e,t),c(e,O,t),c(e,P,t),c(e,Y,t),c(e,A,t),a(A,E),a(A,be),a(A,J),a(J,R),a(R,me),a(R,Z),a(Z,ee),a(R,fe),c(e,te,t),c(e,M,t),c(e,ae,t),c(e,W,t),c(e,le,t),c(e,U,t),c(e,ne,t),c(e,S,t),a(S,oe),a(S,ge),a(S,B),a(B,y),a(y,se),a(y,ke),a(y,ie),a(y,_e),a(y,m),a(m,ve),K(C,m,null),a(m,we),a(m,$e),a(m,Oe),a(m,re),a(m,Ae),a(m,ce),a(m,Se),a(m,ye),a(m,Te),a(m,de),a(m,Ce),a(B,qe),K(q,B,null),c(e,ue,t),c(e,F,t),c(e,he,t),c(e,T,t),a(T,H);for(let u=0;u<$.length;u+=1)$[u]&&$[u].m(H,null);a(T,Pe),a(T,j);for(let u=0;u<w.length;u+=1)w[u]&&w[u].m(j,null);D=!0},p(e,[t]){(!D||t&1)&&i!==(i=e[0].name+"")&&pe(f,i);const u={};t&9&&(u.js=`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${e[3]}');
|
const pb = new PocketBase('${e[3]}');
|
||||||
@@ -103,7 +103,7 @@ import{S as Ee,i as Je,s as Ne,N as Le,O as z,e as o,v as k,b as h,c as I,f as p
|
|||||||
|
|
||||||
// "logout" the last authenticated model
|
// "logout" the last authenticated model
|
||||||
pb.authStore.clear();
|
pb.authStore.clear();
|
||||||
`),v.$set(u),(!D||t&1)&&Q!==(Q=e[0].name+"")&&pe(ee,Q),t&6&&(x=z(e[2]),$=Ue($,t,Me,1,e,x,De,H,Qe,je,null,He)),t&6&&(V=z(e[2]),xe(),w=Ue(w,t,We,1,e,V,Re,j,ze,Ve,null,Fe),Ie())},i(e){if(!D){L(v.$$.fragment,e),L(C.$$.fragment,e),L(q.$$.fragment,e);for(let t=0;t<V.length;t+=1)L(w[t]);D=!0}},o(e){E(v.$$.fragment,e),E(C.$$.fragment,e),E(q.$$.fragment,e);for(let t=0;t<w.length;t+=1)E(w[t]);D=!1},d(e){e&&(c(l),c(d),c(m),c(_),c(O),c(P),c(Y),c(A),c(te),c(M),c(ae),c(W),c(le),c(U),c(ne),c(S),c(ue),c(F),c(he),c(T)),G(v,e),G(C),G(q);for(let t=0;t<$.length;t+=1)$[t].d();for(let t=0;t<w.length;t+=1)w[t].d()}}}function et(s,l,n){let i,{collection:f}=l,g=200,d=[];const m=_=>n(1,g=_.code);return s.$$set=_=>{"collection"in _&&n(0,f=_.collection)},s.$$.update=()=>{s.$$.dirty&1&&n(2,d=[{code:200,body:JSON.stringify({token:"JWT_AUTH_TOKEN",record:Be.dummyCollectionRecord(f),meta:{id:"abc123",name:"John Doe",username:"john.doe",email:"test@example.com",avatarUrl:"https://example.com/avatar.png",accessToken:"...",refreshToken:"...",rawUser:{}}},null,2)},{code:400,body:`
|
`),v.$set(u),(!D||t&1)&&N!==(N=e[0].name+"")&&pe(ee,N),t&6&&(Q=z(e[2]),$=Ue($,t,Me,1,e,Q,De,H,Ne,je,null,He)),t&6&&(V=z(e[2]),Qe(),w=Ue(w,t,We,1,e,V,Re,j,ze,Ve,null,Fe),Ie())},i(e){if(!D){x(v.$$.fragment,e),x(C.$$.fragment,e),x(q.$$.fragment,e);for(let t=0;t<V.length;t+=1)x(w[t]);D=!0}},o(e){L(v.$$.fragment,e),L(C.$$.fragment,e),L(q.$$.fragment,e);for(let t=0;t<w.length;t+=1)L(w[t]);D=!1},d(e){e&&(r(l),r(d),r(b),r(_),r(O),r(P),r(Y),r(A),r(te),r(M),r(ae),r(W),r(le),r(U),r(ne),r(S),r(ue),r(F),r(he),r(T)),I(v,e),I(C),I(q);for(let t=0;t<$.length;t+=1)$[t].d();for(let t=0;t<w.length;t+=1)w[t].d()}}}function et(s,l,n){let i,{collection:f}=l,g=200,d=[];const b=_=>n(1,g=_.code);return s.$$set=_=>{"collection"in _&&n(0,f=_.collection)},s.$$.update=()=>{s.$$.dirty&1&&n(2,d=[{code:200,body:JSON.stringify({token:"JWT_AUTH_TOKEN",record:Be.dummyCollectionRecord(f),meta:{id:"abc123",name:"John Doe",username:"john.doe",email:"test@example.com",avatarUrl:"https://example.com/avatar.png",accessToken:"...",refreshToken:"...",rawUser:{}}},null,2)},{code:400,body:`
|
||||||
{
|
{
|
||||||
"code": 400,
|
"code": 400,
|
||||||
"message": "An error occurred while submitting the form.",
|
"message": "An error occurred while submitting the form.",
|
||||||
@@ -114,4 +114,4 @@ import{S as Ee,i as Je,s as Ne,N as Le,O as z,e as o,v as k,b as h,c as I,f as p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}])},n(3,i=Be.getApiExampleUrl(Ke.baseUrl)),[f,g,d,i,m]}class nt extends Ee{constructor(l){super(),Je(this,l,et,Ze,Ne,{collection:0})}}export{nt as default};
|
`}])},n(3,i=Be.getApiExampleUrl(Ke.baseUrl)),[f,g,d,i,b]}class nt extends xe{constructor(l){super(),Ee(this,l,et,Ze,Je,{collection:0})}}export{nt as default};
|
||||||
Vendored
+10
-10
@@ -1,4 +1,4 @@
|
|||||||
import{S as wt,i as yt,s as $t,N as vt,O as oe,e as n,v as p,b as d,c as ne,f as m,g as r,h as t,m as se,w as De,P as pt,Q as Pt,k as Rt,R as At,n as Ct,t as Z,a as x,o as c,d as ie,C as ft,A as Ot,q as re,r as Tt}from"./index-Bp3jGQ0J.js";import{S as Ut}from"./SdkTabs-DxNNd6Sw.js";import{F as Mt}from"./FieldsQueryParam-zDO3HzQv.js";function ht(s,l,a){const i=s.slice();return i[8]=l[a],i}function bt(s,l,a){const i=s.slice();return i[8]=l[a],i}function Dt(s){let l;return{c(){l=p("email")},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function Et(s){let l;return{c(){l=p("username")},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function Wt(s){let l;return{c(){l=p("username/email")},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function mt(s){let l;return{c(){l=n("strong"),l.textContent="username"},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function _t(s){let l;return{c(){l=p("or")},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function kt(s){let l;return{c(){l=n("strong"),l.textContent="email"},m(a,i){r(a,l,i)},d(a){a&&c(l)}}}function gt(s,l){let a,i=l[8].code+"",g,b,f,u;function _(){return l[7](l[8])}return{key:s,first:null,c(){a=n("button"),g=p(i),b=d(),m(a,"class","tab-item"),re(a,"active",l[3]===l[8].code),this.first=a},m(R,A){r(R,a,A),t(a,g),t(a,b),f||(u=Tt(a,"click",_),f=!0)},p(R,A){l=R,A&16&&i!==(i=l[8].code+"")&&De(g,i),A&24&&re(a,"active",l[3]===l[8].code)},d(R){R&&c(a),f=!1,u()}}}function St(s,l){let a,i,g,b;return i=new vt({props:{content:l[8].body}}),{key:s,first:null,c(){a=n("div"),ne(i.$$.fragment),g=d(),m(a,"class","tab-item"),re(a,"active",l[3]===l[8].code),this.first=a},m(f,u){r(f,a,u),se(i,a,null),t(a,g),b=!0},p(f,u){l=f;const _={};u&16&&(_.content=l[8].body),i.$set(_),(!b||u&24)&&re(a,"active",l[3]===l[8].code)},i(f){b||(Z(i.$$.fragment,f),b=!0)},o(f){x(i.$$.fragment,f),b=!1},d(f){f&&c(a),ie(i)}}}function Lt(s){var rt,ct;let l,a,i=s[0].name+"",g,b,f,u,_,R,A,C,q,Ee,ce,T,de,N,ue,U,ee,We,te,I,Le,pe,le=s[0].name+"",fe,qe,he,V,be,M,me,Be,Q,D,_e,Fe,ke,He,$,Ye,ge,Se,ve,Ne,we,ye,j,$e,E,Pe,Ie,J,W,Re,Ve,Ae,Qe,k,je,B,Je,Ke,ze,Ce,Ge,Oe,Xe,Ze,xe,Te,et,tt,F,Ue,K,Me,L,z,O=[],lt=new Map,at,G,S=[],ot=new Map,H;function nt(e,o){if(e[1]&&e[2])return Wt;if(e[1])return Et;if(e[2])return Dt}let Y=nt(s),P=Y&&Y(s);T=new Ut({props:{js:`
|
import{S as wt,i as yt,s as $t,N as vt,O as oe,b as r,d as ne,t as Z,a as x,r as De,Q as pt,R as Pt,g as Rt,T as Ct,e as Ot,f as c,h as t,m as se,n,u as p,k as d,c as ie,o as m,C as ft,p as Tt,w as re,x as At}from"./index-CRh7dlL-.js";import{S as Ut}from"./SdkTabs-C6hORRCs.js";import{F as Mt}from"./FieldsQueryParam-BKn2QRBU.js";function ht(s,l,a){const i=s.slice();return i[8]=l[a],i}function bt(s,l,a){const i=s.slice();return i[8]=l[a],i}function Dt(s){let l;return{c(){l=p("email")},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function Et(s){let l;return{c(){l=p("username")},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function Wt(s){let l;return{c(){l=p("username/email")},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function mt(s){let l;return{c(){l=n("strong"),l.textContent="username"},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function _t(s){let l;return{c(){l=p("or")},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function kt(s){let l;return{c(){l=n("strong"),l.textContent="email"},m(a,i){c(a,l,i)},d(a){a&&r(l)}}}function gt(s,l){let a,i=l[8].code+"",g,b,f,u;function _(){return l[7](l[8])}return{key:s,first:null,c(){a=n("button"),g=p(i),b=d(),m(a,"class","tab-item"),re(a,"active",l[3]===l[8].code),this.first=a},m(R,C){c(R,a,C),t(a,g),t(a,b),f||(u=At(a,"click",_),f=!0)},p(R,C){l=R,C&16&&i!==(i=l[8].code+"")&&De(g,i),C&24&&re(a,"active",l[3]===l[8].code)},d(R){R&&r(a),f=!1,u()}}}function St(s,l){let a,i,g,b;return i=new vt({props:{content:l[8].body}}),{key:s,first:null,c(){a=n("div"),ie(i.$$.fragment),g=d(),m(a,"class","tab-item"),re(a,"active",l[3]===l[8].code),this.first=a},m(f,u){c(f,a,u),se(i,a,null),t(a,g),b=!0},p(f,u){l=f;const _={};u&16&&(_.content=l[8].body),i.$set(_),(!b||u&24)&&re(a,"active",l[3]===l[8].code)},i(f){b||(x(i.$$.fragment,f),b=!0)},o(f){Z(i.$$.fragment,f),b=!1},d(f){f&&r(a),ne(i)}}}function Lt(s){var rt,ct;let l,a,i=s[0].name+"",g,b,f,u,_,R,C,O,B,Ee,ce,A,de,N,ue,U,ee,We,te,I,Le,pe,le=s[0].name+"",fe,Be,he,V,be,M,me,qe,Q,D,_e,Fe,ke,He,$,Ye,ge,Se,ve,Ne,we,ye,j,$e,E,Pe,Ie,J,W,Re,Ve,Ce,Qe,k,je,q,Je,Ke,ze,Oe,Ge,Te,Xe,Ze,xe,Ae,et,tt,F,Ue,K,Me,L,z,T=[],lt=new Map,at,G,S=[],ot=new Map,H;function nt(e,o){if(e[1]&&e[2])return Wt;if(e[1])return Et;if(e[2])return Dt}let Y=nt(s),P=Y&&Y(s);A=new Ut({props:{js:`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${s[6]}');
|
const pb = new PocketBase('${s[6]}');
|
||||||
@@ -36,17 +36,17 @@ import{S as wt,i as yt,s as $t,N as vt,O as oe,e as n,v as p,b as d,c as ne,f as
|
|||||||
|
|
||||||
// "logout" the last authenticated account
|
// "logout" the last authenticated account
|
||||||
pb.authStore.clear();
|
pb.authStore.clear();
|
||||||
`}});let v=s[1]&&mt(),w=s[1]&&s[2]&&_t(),y=s[2]&&kt();B=new vt({props:{content:"?expand=relField1,relField2.subRelField"}}),F=new Mt({props:{prefix:"record."}});let ae=oe(s[4]);const st=e=>e[8].code;for(let e=0;e<ae.length;e+=1){let o=bt(s,ae,e),h=st(o);lt.set(h,O[e]=gt(h,o))}let X=oe(s[4]);const it=e=>e[8].code;for(let e=0;e<X.length;e+=1){let o=ht(s,X,e),h=it(o);ot.set(h,S[e]=St(h,o))}return{c(){l=n("h3"),a=p("Auth with password ("),g=p(i),b=p(")"),f=d(),u=n("div"),_=n("p"),R=p(`Returns new auth token and account data by a combination of
|
`}});let v=s[1]&&mt(),w=s[1]&&s[2]&&_t(),y=s[2]&&kt();q=new vt({props:{content:"?expand=relField1,relField2.subRelField"}}),F=new Mt({props:{prefix:"record."}});let ae=oe(s[4]);const st=e=>e[8].code;for(let e=0;e<ae.length;e+=1){let o=bt(s,ae,e),h=st(o);lt.set(h,T[e]=gt(h,o))}let X=oe(s[4]);const it=e=>e[8].code;for(let e=0;e<X.length;e+=1){let o=ht(s,X,e),h=it(o);ot.set(h,S[e]=St(h,o))}return{c(){l=n("h3"),a=p("Auth with password ("),g=p(i),b=p(")"),f=d(),u=n("div"),_=n("p"),R=p(`Returns new auth token and account data by a combination of
|
||||||
`),A=n("strong"),P&&P.c(),C=p(`
|
`),C=n("strong"),P&&P.c(),O=p(`
|
||||||
and `),q=n("strong"),q.textContent="password",Ee=p("."),ce=d(),ne(T.$$.fragment),de=d(),N=n("h6"),N.textContent="API details",ue=d(),U=n("div"),ee=n("strong"),ee.textContent="POST",We=d(),te=n("div"),I=n("p"),Le=p("/api/collections/"),pe=n("strong"),fe=p(le),qe=p("/auth-with-password"),he=d(),V=n("div"),V.textContent="Body Parameters",be=d(),M=n("table"),me=n("thead"),me.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr>',Be=d(),Q=n("tbody"),D=n("tr"),_e=n("td"),_e.innerHTML='<div class="inline-flex"><span class="label label-success">Required</span> <span>identity</span></div>',Fe=d(),ke=n("td"),ke.innerHTML='<span class="label">String</span>',He=d(),$=n("td"),Ye=p(`The
|
and `),B=n("strong"),B.textContent="password",Ee=p("."),ce=d(),ie(A.$$.fragment),de=d(),N=n("h6"),N.textContent="API details",ue=d(),U=n("div"),ee=n("strong"),ee.textContent="POST",We=d(),te=n("div"),I=n("p"),Le=p("/api/collections/"),pe=n("strong"),fe=p(le),Be=p("/auth-with-password"),he=d(),V=n("div"),V.textContent="Body Parameters",be=d(),M=n("table"),me=n("thead"),me.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="50%">Description</th></tr>',qe=d(),Q=n("tbody"),D=n("tr"),_e=n("td"),_e.innerHTML='<div class="inline-flex"><span class="label label-success">Required</span> <span>identity</span></div>',Fe=d(),ke=n("td"),ke.innerHTML='<span class="label">String</span>',He=d(),$=n("td"),Ye=p(`The
|
||||||
`),v&&v.c(),ge=d(),w&&w.c(),Se=d(),y&&y.c(),ve=p(`
|
`),v&&v.c(),ge=d(),w&&w.c(),Se=d(),y&&y.c(),ve=p(`
|
||||||
of the record to authenticate.`),Ne=d(),we=n("tr"),we.innerHTML='<td><div class="inline-flex"><span class="label label-success">Required</span> <span>password</span></div></td> <td><span class="label">String</span></td> <td>The auth record password.</td>',ye=d(),j=n("div"),j.textContent="Query parameters",$e=d(),E=n("table"),Pe=n("thead"),Pe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',Ie=d(),J=n("tbody"),W=n("tr"),Re=n("td"),Re.textContent="expand",Ve=d(),Ae=n("td"),Ae.innerHTML='<span class="label">String</span>',Qe=d(),k=n("td"),je=p(`Auto expand record relations. Ex.:
|
of the record to authenticate.`),Ne=d(),we=n("tr"),we.innerHTML='<td><div class="inline-flex"><span class="label label-success">Required</span> <span>password</span></div></td> <td><span class="label">String</span></td> <td>The auth record password.</td>',ye=d(),j=n("div"),j.textContent="Query parameters",$e=d(),E=n("table"),Pe=n("thead"),Pe.innerHTML='<tr><th>Param</th> <th>Type</th> <th width="60%">Description</th></tr>',Ie=d(),J=n("tbody"),W=n("tr"),Re=n("td"),Re.textContent="expand",Ve=d(),Ce=n("td"),Ce.innerHTML='<span class="label">String</span>',Qe=d(),k=n("td"),je=p(`Auto expand record relations. Ex.:
|
||||||
`),ne(B.$$.fragment),Je=p(`
|
`),ie(q.$$.fragment),Je=p(`
|
||||||
Supports up to 6-levels depth nested relations expansion. `),Ke=n("br"),ze=p(`
|
Supports up to 6-levels depth nested relations expansion. `),Ke=n("br"),ze=p(`
|
||||||
The expanded relations will be appended to the record under the
|
The expanded relations will be appended to the record under the
|
||||||
`),Ce=n("code"),Ce.textContent="expand",Ge=p(" property (eg. "),Oe=n("code"),Oe.textContent='"expand": {"relField1": {...}, ...}',Xe=p(`).
|
`),Oe=n("code"),Oe.textContent="expand",Ge=p(" property (eg. "),Te=n("code"),Te.textContent='"expand": {"relField1": {...}, ...}',Xe=p(`).
|
||||||
`),Ze=n("br"),xe=p(`
|
`),Ze=n("br"),xe=p(`
|
||||||
Only the relations to which the request user has permissions to `),Te=n("strong"),Te.textContent="view",et=p(" will be expanded."),tt=d(),ne(F.$$.fragment),Ue=d(),K=n("div"),K.textContent="Responses",Me=d(),L=n("div"),z=n("div");for(let e=0;e<O.length;e+=1)O[e].c();at=d(),G=n("div");for(let e=0;e<S.length;e+=1)S[e].c();m(l,"class","m-b-sm"),m(u,"class","content txt-lg m-b-sm"),m(N,"class","m-b-xs"),m(ee,"class","label label-primary"),m(te,"class","content"),m(U,"class","alert alert-success"),m(V,"class","section-title"),m(M,"class","table-compact table-border m-b-base"),m(j,"class","section-title"),m(E,"class","table-compact table-border m-b-base"),m(K,"class","section-title"),m(z,"class","tabs-header compact combined left"),m(G,"class","tabs-content"),m(L,"class","tabs")},m(e,o){r(e,l,o),t(l,a),t(l,g),t(l,b),r(e,f,o),r(e,u,o),t(u,_),t(_,R),t(_,A),P&&P.m(A,null),t(_,C),t(_,q),t(_,Ee),r(e,ce,o),se(T,e,o),r(e,de,o),r(e,N,o),r(e,ue,o),r(e,U,o),t(U,ee),t(U,We),t(U,te),t(te,I),t(I,Le),t(I,pe),t(pe,fe),t(I,qe),r(e,he,o),r(e,V,o),r(e,be,o),r(e,M,o),t(M,me),t(M,Be),t(M,Q),t(Q,D),t(D,_e),t(D,Fe),t(D,ke),t(D,He),t(D,$),t($,Ye),v&&v.m($,null),t($,ge),w&&w.m($,null),t($,Se),y&&y.m($,null),t($,ve),t(Q,Ne),t(Q,we),r(e,ye,o),r(e,j,o),r(e,$e,o),r(e,E,o),t(E,Pe),t(E,Ie),t(E,J),t(J,W),t(W,Re),t(W,Ve),t(W,Ae),t(W,Qe),t(W,k),t(k,je),se(B,k,null),t(k,Je),t(k,Ke),t(k,ze),t(k,Ce),t(k,Ge),t(k,Oe),t(k,Xe),t(k,Ze),t(k,xe),t(k,Te),t(k,et),t(J,tt),se(F,J,null),r(e,Ue,o),r(e,K,o),r(e,Me,o),r(e,L,o),t(L,z);for(let h=0;h<O.length;h+=1)O[h]&&O[h].m(z,null);t(L,at),t(L,G);for(let h=0;h<S.length;h+=1)S[h]&&S[h].m(G,null);H=!0},p(e,[o]){var dt,ut;(!H||o&1)&&i!==(i=e[0].name+"")&&De(g,i),Y!==(Y=nt(e))&&(P&&P.d(1),P=Y&&Y(e),P&&(P.c(),P.m(A,null)));const h={};o&97&&(h.js=`
|
Only the relations to which the request user has permissions to `),Ae=n("strong"),Ae.textContent="view",et=p(" will be expanded."),tt=d(),ie(F.$$.fragment),Ue=d(),K=n("div"),K.textContent="Responses",Me=d(),L=n("div"),z=n("div");for(let e=0;e<T.length;e+=1)T[e].c();at=d(),G=n("div");for(let e=0;e<S.length;e+=1)S[e].c();m(l,"class","m-b-sm"),m(u,"class","content txt-lg m-b-sm"),m(N,"class","m-b-xs"),m(ee,"class","label label-primary"),m(te,"class","content"),m(U,"class","alert alert-success"),m(V,"class","section-title"),m(M,"class","table-compact table-border m-b-base"),m(j,"class","section-title"),m(E,"class","table-compact table-border m-b-base"),m(K,"class","section-title"),m(z,"class","tabs-header compact combined left"),m(G,"class","tabs-content"),m(L,"class","tabs")},m(e,o){c(e,l,o),t(l,a),t(l,g),t(l,b),c(e,f,o),c(e,u,o),t(u,_),t(_,R),t(_,C),P&&P.m(C,null),t(_,O),t(_,B),t(_,Ee),c(e,ce,o),se(A,e,o),c(e,de,o),c(e,N,o),c(e,ue,o),c(e,U,o),t(U,ee),t(U,We),t(U,te),t(te,I),t(I,Le),t(I,pe),t(pe,fe),t(I,Be),c(e,he,o),c(e,V,o),c(e,be,o),c(e,M,o),t(M,me),t(M,qe),t(M,Q),t(Q,D),t(D,_e),t(D,Fe),t(D,ke),t(D,He),t(D,$),t($,Ye),v&&v.m($,null),t($,ge),w&&w.m($,null),t($,Se),y&&y.m($,null),t($,ve),t(Q,Ne),t(Q,we),c(e,ye,o),c(e,j,o),c(e,$e,o),c(e,E,o),t(E,Pe),t(E,Ie),t(E,J),t(J,W),t(W,Re),t(W,Ve),t(W,Ce),t(W,Qe),t(W,k),t(k,je),se(q,k,null),t(k,Je),t(k,Ke),t(k,ze),t(k,Oe),t(k,Ge),t(k,Te),t(k,Xe),t(k,Ze),t(k,xe),t(k,Ae),t(k,et),t(J,tt),se(F,J,null),c(e,Ue,o),c(e,K,o),c(e,Me,o),c(e,L,o),t(L,z);for(let h=0;h<T.length;h+=1)T[h]&&T[h].m(z,null);t(L,at),t(L,G);for(let h=0;h<S.length;h+=1)S[h]&&S[h].m(G,null);H=!0},p(e,[o]){var dt,ut;(!H||o&1)&&i!==(i=e[0].name+"")&&De(g,i),Y!==(Y=nt(e))&&(P&&P.d(1),P=Y&&Y(e),P&&(P.c(),P.m(C,null)));const h={};o&97&&(h.js=`
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
|
|
||||||
const pb = new PocketBase('${e[6]}');
|
const pb = new PocketBase('${e[6]}');
|
||||||
@@ -84,7 +84,7 @@ import{S as wt,i as yt,s as $t,N as vt,O as oe,e as n,v as p,b as d,c as ne,f as
|
|||||||
|
|
||||||
// "logout" the last authenticated account
|
// "logout" the last authenticated account
|
||||||
pb.authStore.clear();
|
pb.authStore.clear();
|
||||||
`),T.$set(h),(!H||o&1)&&le!==(le=e[0].name+"")&&De(fe,le),e[1]?v||(v=mt(),v.c(),v.m($,ge)):v&&(v.d(1),v=null),e[1]&&e[2]?w||(w=_t(),w.c(),w.m($,Se)):w&&(w.d(1),w=null),e[2]?y||(y=kt(),y.c(),y.m($,ve)):y&&(y.d(1),y=null),o&24&&(ae=oe(e[4]),O=pt(O,o,st,1,e,ae,lt,z,Pt,gt,null,bt)),o&24&&(X=oe(e[4]),Rt(),S=pt(S,o,it,1,e,X,ot,G,At,St,null,ht),Ct())},i(e){if(!H){Z(T.$$.fragment,e),Z(B.$$.fragment,e),Z(F.$$.fragment,e);for(let o=0;o<X.length;o+=1)Z(S[o]);H=!0}},o(e){x(T.$$.fragment,e),x(B.$$.fragment,e),x(F.$$.fragment,e);for(let o=0;o<S.length;o+=1)x(S[o]);H=!1},d(e){e&&(c(l),c(f),c(u),c(ce),c(de),c(N),c(ue),c(U),c(he),c(V),c(be),c(M),c(ye),c(j),c($e),c(E),c(Ue),c(K),c(Me),c(L)),P&&P.d(),ie(T,e),v&&v.d(),w&&w.d(),y&&y.d(),ie(B),ie(F);for(let o=0;o<O.length;o+=1)O[o].d();for(let o=0;o<S.length;o+=1)S[o].d()}}}function qt(s,l,a){let i,g,b,f,{collection:u}=l,_=200,R=[];const A=C=>a(3,_=C.code);return s.$$set=C=>{"collection"in C&&a(0,u=C.collection)},s.$$.update=()=>{var C,q;s.$$.dirty&1&&a(2,g=(C=u==null?void 0:u.options)==null?void 0:C.allowEmailAuth),s.$$.dirty&1&&a(1,b=(q=u==null?void 0:u.options)==null?void 0:q.allowUsernameAuth),s.$$.dirty&6&&a(5,f=b&&g?"YOUR_USERNAME_OR_EMAIL":b?"YOUR_USERNAME":"YOUR_EMAIL"),s.$$.dirty&1&&a(4,R=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:ft.dummyCollectionRecord(u)},null,2)},{code:400,body:`
|
`),A.$set(h),(!H||o&1)&&le!==(le=e[0].name+"")&&De(fe,le),e[1]?v||(v=mt(),v.c(),v.m($,ge)):v&&(v.d(1),v=null),e[1]&&e[2]?w||(w=_t(),w.c(),w.m($,Se)):w&&(w.d(1),w=null),e[2]?y||(y=kt(),y.c(),y.m($,ve)):y&&(y.d(1),y=null),o&24&&(ae=oe(e[4]),T=pt(T,o,st,1,e,ae,lt,z,Pt,gt,null,bt)),o&24&&(X=oe(e[4]),Rt(),S=pt(S,o,it,1,e,X,ot,G,Ct,St,null,ht),Ot())},i(e){if(!H){x(A.$$.fragment,e),x(q.$$.fragment,e),x(F.$$.fragment,e);for(let o=0;o<X.length;o+=1)x(S[o]);H=!0}},o(e){Z(A.$$.fragment,e),Z(q.$$.fragment,e),Z(F.$$.fragment,e);for(let o=0;o<S.length;o+=1)Z(S[o]);H=!1},d(e){e&&(r(l),r(f),r(u),r(ce),r(de),r(N),r(ue),r(U),r(he),r(V),r(be),r(M),r(ye),r(j),r($e),r(E),r(Ue),r(K),r(Me),r(L)),P&&P.d(),ne(A,e),v&&v.d(),w&&w.d(),y&&y.d(),ne(q),ne(F);for(let o=0;o<T.length;o+=1)T[o].d();for(let o=0;o<S.length;o+=1)S[o].d()}}}function Bt(s,l,a){let i,g,b,f,{collection:u}=l,_=200,R=[];const C=O=>a(3,_=O.code);return s.$$set=O=>{"collection"in O&&a(0,u=O.collection)},s.$$.update=()=>{var O,B;s.$$.dirty&1&&a(2,g=(O=u==null?void 0:u.options)==null?void 0:O.allowEmailAuth),s.$$.dirty&1&&a(1,b=(B=u==null?void 0:u.options)==null?void 0:B.allowUsernameAuth),s.$$.dirty&6&&a(5,f=b&&g?"YOUR_USERNAME_OR_EMAIL":b?"YOUR_USERNAME":"YOUR_EMAIL"),s.$$.dirty&1&&a(4,R=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:ft.dummyCollectionRecord(u)},null,2)},{code:400,body:`
|
||||||
{
|
{
|
||||||
"code": 400,
|
"code": 400,
|
||||||
"message": "Failed to authenticate.",
|
"message": "Failed to authenticate.",
|
||||||
@@ -95,4 +95,4 @@ import{S as wt,i as yt,s as $t,N as vt,O as oe,e as n,v as p,b as d,c as ne,f as
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}])},a(6,i=ft.getApiExampleUrl(Ot.baseUrl)),[u,b,g,_,R,f,i,A]}class Yt extends wt{constructor(l){super(),yt(this,l,qt,Lt,$t,{collection:0})}}export{Yt as default};
|
`}])},a(6,i=ft.getApiExampleUrl(Tt.baseUrl)),[u,b,g,_,R,f,i,C]}class Yt extends wt{constructor(l){super(),yt(this,l,Bt,Lt,$t,{collection:0})}}export{Yt as default};
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
import{S as wt,i as Rt,s as Yt,e as Tt,f as Wt,U as OO,g as _t,x as BO,o as qt,J as vt,K as Ut,L as zt,I as Vt,C as jt,M as Gt}from"./index-Bp3jGQ0J.js";import{P as Ct,N as At,w as Et,D as Nt,x as qO,T as tO,I as vO,y as B,z as l,A as Mt,L as J,B as L,F as v,G as K,H as UO,J as F,v as G,K as _e,M as qe,O as ve,E as q,Q as Ue,R as S,U as It,V as Dt,W as ze,X as Bt,Y as Jt,b as C,e as Lt,f as Kt,g as Ft,i as Ht,j as Oa,k as ea,u as ta,l as aa,m as ra,r as ia,n as sa,o as oa,c as la,d as na,s as ca,h as Qa,a as ha,p as ua,q as JO,C as eO}from"./index-BztyTJOx.js";var LO={};class sO{constructor(O,a,t,r,s,i,o,n,Q,u=0,c){this.p=O,this.stack=a,this.state=t,this.reducePos=r,this.pos=s,this.score=i,this.buffer=o,this.bufferBase=n,this.curContext=Q,this.lookAhead=u,this.parent=c}toString(){return`[${this.stack.filter((O,a)=>a%3==0).concat(this.state)}]@${this.pos}${this.score?"!"+this.score:""}`}static start(O,a,t=0){let r=O.parser.context;return new sO(O,[],a,t,t,0,[],0,r?new KO(r,r.start):null,0,null)}get context(){return this.curContext?this.curContext.context:null}pushState(O,a){this.stack.push(this.state,a,this.bufferBase+this.buffer.length),this.state=O}reduce(O){var a;let t=O>>19,r=O&65535,{parser:s}=this.p;this.reducePos<this.pos-25&&this.setLookAhead(this.pos);let i=s.dynamicPrecedence(r);if(i&&(this.score+=i),t==0){this.pushState(s.getGoto(this.state,r,!0),this.reducePos),r<s.minRepeatTerm&&this.storeNode(r,this.reducePos,this.reducePos,4,!0),this.reduceContext(r,this.reducePos);return}let o=this.stack.length-(t-1)*3-(O&262144?6:0),n=o?this.stack[o-2]:this.p.ranges[0].from,Q=this.reducePos-n;Q>=2e3&&!(!((a=this.p.parser.nodeSet.types[r])===null||a===void 0)&&a.isAnonymous)&&(n==this.p.lastBigReductionStart?(this.p.bigReductionCount++,this.p.lastBigReductionSize=Q):this.p.lastBigReductionSize<Q&&(this.p.bigReductionCount=1,this.p.lastBigReductionStart=n,this.p.lastBigReductionSize=Q));let u=o?this.stack[o-1]:0,c=this.bufferBase+this.buffer.length-u;if(r<s.minRepeatTerm||O&131072){let f=s.stateFlag(this.state,1)?this.pos:this.reducePos;this.storeNode(r,n,f,c+4,!0)}if(O&262144)this.state=this.stack[o];else{let f=this.stack[o-3];this.state=s.getGoto(f,r,!0)}for(;this.stack.length>o;)this.stack.pop();this.reduceContext(r,n)}storeNode(O,a,t,r=4,s=!1){if(O==0&&(!this.stack.length||this.stack[this.stack.length-1]<this.buffer.length+this.bufferBase)){let i=this,o=this.buffer.length;if(o==0&&i.parent&&(o=i.bufferBase-i.parent.bufferBase,i=i.parent),o>0&&i.buffer[o-4]==0&&i.buffer[o-1]>-1){if(a==t)return;if(i.buffer[o-2]>=a){i.buffer[o-2]=t;return}}}if(!s||this.pos==t)this.buffer.push(O,a,t,r);else{let i=this.buffer.length;if(i>0&&this.buffer[i-4]!=0)for(;i>0&&this.buffer[i-2]>t;)this.buffer[i]=this.buffer[i-4],this.buffer[i+1]=this.buffer[i-3],this.buffer[i+2]=this.buffer[i-2],this.buffer[i+3]=this.buffer[i-1],i-=4,r>4&&(r-=4);this.buffer[i]=O,this.buffer[i+1]=a,this.buffer[i+2]=t,this.buffer[i+3]=r}}shift(O,a,t,r){if(O&131072)this.pushState(O&65535,this.pos);else if(O&262144)this.pos=r,this.shiftContext(a,t),a<=this.p.parser.maxNode&&this.buffer.push(a,t,r,4);else{let s=O,{parser:i}=this.p;(r>this.pos||a<=i.maxNode)&&(this.pos=r,i.stateFlag(s,1)||(this.reducePos=r)),this.pushState(s,t),this.shiftContext(a,t),a<=i.maxNode&&this.buffer.push(a,t,r,4)}}apply(O,a,t,r){O&65536?this.reduce(O):this.shift(O,a,t,r)}useNode(O,a){let t=this.p.reused.length-1;(t<0||this.p.reused[t]!=O)&&(this.p.reused.push(O),t++);let r=this.pos;this.reducePos=this.pos=r+O.length,this.pushState(a,r),this.buffer.push(t,r,this.reducePos,-1),this.curContext&&this.updateContext(this.curContext.tracker.reuse(this.curContext.context,O,this,this.p.stream.reset(this.pos-O.length)))}split(){let O=this,a=O.buffer.length;for(;a>0&&O.buffer[a-2]>O.reducePos;)a-=4;let t=O.buffer.slice(a),r=O.bufferBase+a;for(;O&&r==O.bufferBase;)O=O.parent;return new sO(this.p,this.stack.slice(),this.state,this.reducePos,this.pos,this.score,t,r,this.curContext,this.lookAhead,O)}recoverByDelete(O,a){let t=O<=this.p.parser.maxNode;t&&this.storeNode(O,this.pos,a,4),this.storeNode(0,this.pos,a,t?8:4),this.pos=this.reducePos=a,this.score-=190}canShift(O){for(let a=new pa(this);;){let t=this.p.parser.stateSlot(a.state,4)||this.p.parser.hasAction(a.state,O);if(t==0)return!1;if(!(t&65536))return!0;a.reduce(t)}}recoverByInsert(O){if(this.stack.length>=300)return[];let a=this.p.parser.nextStates(this.state);if(a.length>8||this.stack.length>=120){let r=[];for(let s=0,i;s<a.length;s+=2)(i=a[s+1])!=this.state&&this.p.parser.hasAction(i,O)&&r.push(a[s],i);if(this.stack.length<120)for(let s=0;r.length<8&&s<a.length;s+=2){let i=a[s+1];r.some((o,n)=>n&1&&o==i)||r.push(a[s],i)}a=r}let t=[];for(let r=0;r<a.length&&t.length<4;r+=2){let s=a[r+1];if(s==this.state)continue;let i=this.split();i.pushState(s,this.pos),i.storeNode(0,i.pos,i.pos,4,!0),i.shiftContext(a[r],this.pos),i.reducePos=this.pos,i.score-=200,t.push(i)}return t}forceReduce(){let{parser:O}=this.p,a=O.stateSlot(this.state,5);if(!(aLine truncated
|
|
||||||
\${}
|
|
||||||
} catch (\${error}) {
|
|
||||||
\${}
|
|
||||||
}`,{label:"try",detail:"/ catch block",type:"keyword"}),S("if (${}) {\n ${}\n}",{label:"if",detail:"block",type:"keyword"}),S(`if (\${}) {
|
|
||||||
\${}
|
|
||||||
} else {
|
|
||||||
\${}
|
|
||||||
}`,{label:"if",detail:"/ else block",type:"keyword"}),S(`class \${name} {
|
|
||||||
constructor(\${params}) {
|
|
||||||
\${}
|
|
||||||
}
|
|
||||||
}`,{label:"class",detail:"definition",type:"keyword"}),S('import {${names}} from "${module}"\n${}',{label:"import",detail:"named",type:"keyword"}),S('import ${name} from "${module}"\n${}',{label:"import",detail:"default",type:"keyword"})],oi=tt.concat([S("interface ${name} {\n ${}\n}",{label:"interface",detail:"definition",type:"keyword"}),S("type ${name} = ${type}",{label:"type",detail:"definition",type:"keyword"}),S("enum ${name} {\n ${}\n}",{label:"enum",detail:"definition",type:"keyword"})]),$e=new _e,at=new Set(["Script","Block","FunctionExpression","FunctionDeclaration","ArrowFunction","MethodDeclaration","ForStatement"]);function A(e){return(O,a)=>{let t=O.node.getChild("VariableDefinition");return t&&a(t,e),!0}}const li=["FunctionDeclaration"],ni={FunctionDeclaration:A("function"),ClassDeclaration:A("class"),ClassExpression:()=>!0,EnumDeclaration:A("constant"),TypeAliasDeclaration:A("type"),NamespaceDeclaration:A("namespace"),VariableDefinition(e,O){e.matchContext(li)||O(e,"variable")},TypeDefinition(e,O){O(e,"type")},__proto__:null};function rt(e,O){let a=$e.get(O);if(a)return a;let t=[],r=!0;function s(i,o){let n=e.sliceString(i.from,i.to);t.push({label:n,type:o})}return O.cursor(vO.IncludeAnonymous).iterate(i=>{if(r)r=!1;else if(i.name){let o=ni[i.name];if(o&&o(i,s)||at.has(i.name))return!1}else if(i.to-i.from>8192){for(let o of rt(e,i.node))t.push(o);return!1}}),$e.set(O,t),t}const Pe=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,it=["TemplateString","String","RegExp","LineComment","BlockComment","VariableDefinition","TypeDefinition","Label","PropertyDefinition","PropertyName","PrivatePropertyDefinition","PrivatePropertyName",".","?."];function ci(e){let O=G(e.state).resolveInner(e.pos,-1);if(it.indexOf(O.name)>-1)return null;let a=O.name=="VariableName"||O.to-O.from<20&&Pe.test(e.state.sliceDoc(O.from,O.to));if(!a&&!e.explicit)return null;let t=[];for(let r=O;r;r=r.parent)at.has(r.name)&&(t=t.concat(rt(e.state.doc,r)));return{options:t,from:a?O.from:e.pos,validFor:Pe}}const y=J.define({name:"javascript",parser:si.configure({props:[L.add({IfStatement:v({except:/^\s*({|else\b)/}),TryStatement:v({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:It,SwitchBody:e=>{let O=e.textAfter,a=/^\s*\}/.test(O),t=/^\s*(case|default)\b/.test(O);return e.baseIndent+(a?0:t?1:2)*e.unit},Block:Dt({closing:"}"}),ArrowFunction:e=>e.baseIndent+e.unit,"TemplateString BlockComment":()=>null,"Statement Property":v({except:/^{/}),JSXElement(e){let O=/^\s*<\//.test(e.textAfter);return e.lineIndent(e.node.from)+(O?0:e.unit)},JSXEscape(e){let O=/\s*\}/.test(e.textAfter);return e.lineIndent(e.node.from)+(O?0:e.unit)},"JSXOpenTag JSXSelfClosingTag"(e){return e.column(e.node.from)+e.unit}}),K.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":UO,BlockComment(e){return{from:e.from+2,to:e.to-2}}})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"`"]},commentTokens:{line:"//",block:{open:"/*",close:"*/"}},indentOnInput:/^\s*(?:case |default:|\{|\}|<\/)$/,wordChars:"$"}}),st={test:e=>/^JSX/.test(e.name),facet:Bt({commentTokens:{block:{open:"{/*",close:"*/}"}}})},ot=y.configure({dialect:"ts"},"typescript"),lt=y.configure({dialect:"jsx",props:[ze.add(e=>e.isTop?[st]:void 0)]}),nt=y.configure({dialect:"jsx ts",props:[ze.add(e=>e.isTop?[st]:void 0)]},"typescript");let ct=e=>({label:e,type:"keyword"});const Qt="break case const continue default delete export extends false finally in instanceof let new return static super switch this throw true typeof var yield".split(" ").map(ct),Qi=Qt.concat(["declare","implements","private","protected","public"].map(ct));function ht(e={}){let O=e.jsx?e.typescript?nt:lt:e.typescript?ot:y,a=e.typescript?oi.concat(Qi):tt.concat(Qt);return new F(O,[y.data.of({autocomplete:qe(it,ve(a))}),y.data.of({autocomplete:ci}),e.jsx?pi:[]])}function hi(e){for(;;){if(e.name=="JSXOpenTag"||e.name=="JSXSelfClosingTag"||e.name=="JSXFragmentTag")return e;if(e.name=="JSXEscape"||!e.parent)return null;e=e.parent}}function me(e,O,a=e.length){for(let t=O==null?void 0:O.firstChild;t;t=t.nextSibling)if(t.name=="JSXIdentifier"||t.name=="JSXBuiltin"||t.name=="JSXNamespacedName"||t.name=="JSXMemberExpression")return e.sliceString(t.from,Math.min(t.to,a));return""}const ui=typeof navigator=="object"&&/Android\b/.test(navigator.userAgent),pi=q.inputHandler.of((e,O,a,t,r)=>{if((ui?e.composing:e.compositionStarted)||e.state.readOnly||O!=a||t!=">"&&t!="/"||!y.isActiveAt(e.state,O,-1))return!1;let s=r(),{state:i}=s,o=i.changeByRange(n=>{var Q;let{head:u}=n,c=G(i).resolveInner(u-1,-1),f;if(c.name=="JSXStartTag"&&(c=c.parent),!(i.doc.sliceString(u-1,u)!=t||c.name=="JSXAttributeValue"&&c.to>u)){if(t==">"&&c.name=="JSXFragmentTag")return{range:n,changes:{from:u,insert:"</>"}};if(t=="/"&&c.name=="JSXStartCloseTag"){let h=c.parent,d=h.parent;if(d&&h.from==u-2&&((f=me(i.doc,d.firstChild,u))||((Q=d.firstChild)===null||Q===void 0?void 0:Q.name)=="JSXFragmentTag")){let P=`${f}>`;return{range:Ue.cu
Line truncated
|
|
||||||
`;function Zt(e,O,a){let t=Object.create(null);t.true=t.false=Yi,t.null=t.unknown=Ti;for(let r of e.split(" "))r&&(t[r]=gt);for(let r of O.split(" "))r&&(t[r]=St);for(let r of(a||"").split(" "))r&&(t[r]=Mi);return t}const Li="array binary bit boolean char character clob date decimal double float int integer interval large national nchar nclob numeric object precision real smallint time timestamp varchar varying ",Ki="absolute action add after all allocate alter and any are as asc assertion at authorization before begin between both breadth by call cascade cascaded case cast catalog check close collate collation column commit condition connect connection constraint constraints constructor continue corresponding count create cross cube current current_date current_default_transform_group current_transform_group_for_type current_path current_role current_time current_timestamp current_user cursor cycle data day deallocate declare default deferrable deferred delete depth deref desc describe descriptor deterministic diagnostics disconnect distinct do domain drop dynamic each else elseif end end-exec equals escape except exception exec execute exists exit external fetch first for foreign found from free full function general get global go goto grant group grouping handle having hold hour identity if immediate in indicator initially inner inout input insert intersect into is isolation join key language last lateral leading leave left level like limit local localtime localtimestamp locator loop map match method minute modifies module month names natural nesting new next no none not of old on only open option or order ordinality out outer output overlaps pad parameter partial path prepare preserve primary prior privileges procedure public read reads recursive redo ref references referencing relative release repeat resignal restrict result return returns revoke right role rollback rollup routine row rows savepoint schema scroll search second section select session session_user set sets signal similar size some space specific specifictype sql sqlexception sqlstate sqlwarning start state static system_user table temporary then timezone_hour timezone_minute to trailing transaction translation treat trigger under undo union unique unnest until update usage user using value values view when whenever where while with without work write year zone ",WO={backslashEscapes:!1,hashComments:!1,spaceAfterDashes:!1,slashComments:!1,doubleQuotedStrings:!1,doubleDollarQuotedStrings:!1,unquotedBitLiterals:!1,treatBitsAsBytes:!1,charSetCasts:!1,plsqlQuotingMechanism:!1,operatorChars:"*+-%<>!=&|~^/",specialVar:"?",identifierQuotes:'"',caseInsensitiveIdentifiers:!1,words:Zt(Ki,Li)};function Fi(e,O,a,t){let r={};for(let s in WO)r[s]=(e.hasOwnProperty(s)?e:WO)[s];return O&&(r.words=Zt(O,a||"",t)),r}function bt(e){return new k(O=>{var a;let{next:t}=O;if(O.advance(),W(t,xO)){for(;W(O.next,xO);)O.advance();O.acceptToken(wi)}else if(t==36&&e.doubleDollarQuotedStrings){let r=TO(O,"");O.next==36&&(O.advance(),Di(O,r),O.acceptToken(U))}else if(t==39||t==34&&e.doubleQuotedStrings)_(O,t,e.backslashEscapes),O.acceptToken(U);else if(t==35&&e.hashComments||t==47&&O.next==47&&e.slashComments)we(O),O.acceptToken(be);else if(t==45&&O.next==45&&(!e.spaceAfterDashes||O.peek(1)==32))we(O),O.acceptToken(be);else if(t==47&&O.next==42){O.advance();for(let r=1;;){let s=O.next;if(O.next<0)break;if(O.advance(),s==42&&O.next==47){if(r--,O.advance(),!r)break}else s==47&&O.next==42&&(r++,O.advance())}O.acceptToken(Ri)}else if((t==101||t==69)&&O.next==39)O.advance(),_(O,39,!0),O.acceptToken(U);else if((t==110||t==78)&&O.next==39&&e.charSetCasts)O.advance(),_(O,39,e.backslashEscapes),O.acceptToken(U);else if(t==95&&e.charSetCasts)for(let r=0;;r++){if(O.next==39&&r>1){O.advance(),_(O,39,e.backslashEscapes),O.acceptToken(U);break}if(!YO(O.next))break;O.advance()}else if(e.plsqlQuotingMechanism&&(t==113||t==81)&&O.next==39&&O.peek(1)>0&&!W(O.peek(1),xO)){let r=O.peek(1);O.advance(2),Bi(O,r),O.acceptToken(U)}else if(t==40)O.acceptToken(Wi);else if(t==41)O.acceptToken(_i);else if(t==123)O.acceptToken(qi);else if(t==125)O.acceptToken(vi);else if(t==91)O.acceptToken(Ui);else if(t==93)O.acceptToken(zi);else if(t==59)O.acceptToken(Vi);else if(e.unquotedBitLiterals&&t==48&&O.next==98)O.advance(),Xe(O),O.acceptToken(xe);else if((t==98||t==66)&&(O.next==39||O.next==34)){const r=O.next;O.advance(),e.treatBitsAsBytes?(_(O,r,e.backslashEscapes),O.acceptToken(Ni)):(Xe(O,r),O.acceptToken(xe))}else if(t==48&&(O.next==120||O.next==88)||(t==120||t==88)&&O.next==39){let r=O.next==39;for(O.advance();Ii(O.next);)O.advance();r&&O.next==39&&O.advance(),O.acceptToken(kO)}else if(t==46&&O.next>=48&&O.next<=57)ye(O,!0),O.acceptToken(kO);else if(t==46)O.acceptToken(ji);else if(t>=48&&t<=57)ye(O,!1),O.acceptToken(kO);else if(W(t,e.operatorChars)){for(;W(O.next,e.operatorChars);)O.advance();O.acceptToken(Gi)}else if(W(t,e.specialVar))O.next==t&&O.advance(),Ji(O),O.acceptToken(Ai);else if(W(t,e.ide
Line truncated
|
|
||||||
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user