(experimental) upgraded to encoding/json/v2

This commit is contained in:
Gani Georgiev
2026-08-18 18:16:22 +03:00
parent 4d4275c9aa
commit 97dd775455
125 changed files with 433 additions and 364 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ package apis
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"errors"
"io"
"mime/multipart"
+1 -1
View File
@@ -1617,7 +1617,7 @@ func TestCollectionOAuth2Providers(t *testing.T) {
},
ExpectedStatus: 200,
ExpectedContent: []string{
`{"name":"oidc3","displayName":"OIDC","logo":"\u003csvg`,
`{"name":"oidc3","displayName":"OIDC","logo":"<svg`,
},
NotExpectedContent: []string{
`"order":`,
+1 -1
View File
@@ -2,7 +2,7 @@ package apis
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"log/slog"
+4 -2
View File
@@ -2,7 +2,7 @@ package apis_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"net/http"
@@ -1171,7 +1171,9 @@ func TestRealtimeRecordResolve(t *testing.T) {
var mu sync.Mutex
notify := func(clientId string, eventData []byte) {
data := struct{ Action string }{}
data := struct {
Action string `json:"action"`
}{}
_ = json.Unmarshal(eventData, &data)
mu.Lock()
+1 -1
View File
@@ -54,7 +54,7 @@ func TestRecordAuthMethodsList(t *testing.T) {
`"providers":[{`,
`"name":"google"`,
`"name":"gitlab"`,
`"logo":"\u003csvg`,
`"logo":"<svg`,
`"logo":""`, // for the legacy fields
`"state":`,
`"displayName":`,
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"bytes"
"context"
"database/sql"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
+1 -1
View File
@@ -1,7 +1,7 @@
package apis
import (
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
"strings"
+1 -1
View File
@@ -1,7 +1,7 @@
package apis_test
import (
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
"net/http/httptest"
+7 -2
View File
@@ -4,7 +4,8 @@ import (
"cmp"
"context"
"database/sql"
"encoding/json"
"encoding/json/jsontext"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -186,7 +187,11 @@ func (app *BaseApp) ImportCollections(toImport []map[string]any, deleteMissing b
)
if err := validator.run(); err != nil {
// serialize the validation error(s)
serializedErr, _ := json.MarshalIndent(err, "", " ")
serializedErr, _ := json.Marshal(
err,
jsontext.WithIndentPrefix(""),
jsontext.WithIndent(" "),
)
return validation.Errors{"collections": validation.NewError(
"validation_collections_import_failure",
+2 -2
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"strings"
"testing"
@@ -449,7 +449,7 @@ func TestImportCollectionsCreateRules(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(collection)
raw, err := json.Marshal(collection, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+10 -9
View File
@@ -1,7 +1,7 @@
package core
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"strconv"
"strings"
@@ -522,8 +522,6 @@ func (m *Collection) unmarshalRawOptions() error {
// For new/"blank" Collection models it replaces the model with a factory
// instance and then unmarshal the provided data one on top of it.
func (m *Collection) UnmarshalJSON(b []byte) error {
type alias *Collection
// initialize the default fields
// (e.g. in case the collection was NOT created using the designated factories)
if m.IsNew() && m.Type == "" {
@@ -540,7 +538,8 @@ func (m *Collection) UnmarshalJSON(b []byte) error {
*m = *blank
}
return json.Unmarshal(b, alias(m))
type alias Collection
return json.Unmarshal(b, (*alias)(m))
}
// MarshalJSON implements the [json.Marshaler] interface.
@@ -550,10 +549,12 @@ func (m *Collection) UnmarshalJSON(b []byte) error {
func (m Collection) MarshalJSON() ([]byte, error) {
switch m.Type {
case CollectionTypeView:
return json.Marshal(struct {
alias := struct {
baseCollection
collectionViewOptions
}{m.baseCollection, m.collectionViewOptions})
}{m.baseCollection, m.collectionViewOptions}
return json.Marshal(alias, json.Deterministic(true))
case CollectionTypeAuth:
alias := struct {
baseCollection
@@ -582,15 +583,15 @@ func (m Collection) MarshalJSON() ([]byte, error) {
alias.OAuth2.Providers = redactedProviders
}
return json.Marshal(alias)
return json.Marshal(alias, json.Deterministic(true))
default:
return json.Marshal(m.baseCollection)
return json.Marshal(m.baseCollection, json.Deterministic(true))
}
}
// String returns a string representation of the current collection.
func (m Collection) String() string {
raw, _ := json.Marshal(m)
raw, _ := m.MarshalJSON()
return string(raw)
}
+3 -3
View File
@@ -2,7 +2,7 @@ package core_test
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"fmt"
"strings"
"testing"
@@ -1016,8 +1016,8 @@ func TestOAuth2ProviderConfigInitProvider(t *testing.T) {
t.Fatalf("Expected PKCE %v, got %v", *s.expectedConfig.PKCE, provider.PKCE())
}
rawMeta, _ := json.Marshal(provider.Extra())
expectedMeta, _ := json.Marshal(s.expectedConfig.Extra)
rawMeta, _ := json.Marshal(provider.Extra(), json.Deterministic(true))
expectedMeta, _ := json.Marshal(s.expectedConfig.Extra, json.Deterministic(true))
if !bytes.Equal(rawMeta, expectedMeta) {
t.Fatalf("Expected PKCE %v, got %v", *s.expectedConfig.PKCE, provider.PKCE())
}
+4 -4
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -618,7 +618,7 @@ func TestCollectionUnmarshalJSON(t *testing.T) {
t.Fatal(err)
}
rawResult, err := json.Marshal(collection)
rawResult, err := json.Marshal(collection, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -829,7 +829,7 @@ func TestCollectionDBExport(t *testing.T) {
},
{
core.CollectionTypeAuth,
`{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":null,"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":null},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
`{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":[],"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":[]},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`,
},
}
@@ -860,7 +860,7 @@ func TestCollectionDBExport(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(result)
raw, err := json.Marshal(result, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+3 -3
View File
@@ -3,7 +3,7 @@ package core
import (
"bytes"
"database/sql"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -324,12 +324,12 @@ func resaveViewsWithChangedFields(app App, excludeIds ...string) error {
f.SetId("")
}
encodedNewFields, err := json.Marshal(newFields)
encodedNewFields, err := json.Marshal(newFields, json.Deterministic(true))
if err != nil {
return err
}
encodedOldFields, err := json.Marshal(oldFields)
encodedOldFields, err := json.Marshal(oldFields, json.Deterministic(true))
if err != nil {
return err
}
+3 -3
View File
@@ -2,7 +2,7 @@ package core_test
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"testing"
"github.com/pocketbase/dbx"
@@ -278,12 +278,12 @@ func TestSingleVsMultipleValuesNormalization(t *testing.T) {
t.Fatalf("Failed to load record: %v", err)
}
encodedResult, err := json.Marshal(result)
encodedResult, err := json.Marshal(result, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to encode result: %v", err)
}
encodedExpectation, err := json.Marshal(s.expected)
encodedExpectation, err := json.Marshal(s.expected, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to encode expectation: %v", err)
}
+6 -2
View File
@@ -3,7 +3,7 @@ package core_test
import (
"context"
"database/sql"
"encoding/json"
"encoding/json/v2"
"fmt"
"slices"
"testing"
@@ -120,7 +120,11 @@ func TestTableInfo(t *testing.T) {
t.Run(fmt.Sprintf("%d_%s", i, s.tableName), func(t *testing.T) {
rows, _ := app.TableInfo(s.tableName)
raw, err := json.Marshal(rows)
raw, err := json.Marshal(
rows,
json.Deterministic(true),
json.FormatNilSliceAsNull(true),
)
if err != nil {
t.Fatal(err)
}
+5 -5
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"net/http"
"strings"
"testing"
@@ -183,7 +183,7 @@ func TestRequestEventRequestInfo(t *testing.T) {
t.Fatalf("Failed to resolve request info: %v", err)
}
raw, err := json.Marshal(info)
raw, err := json.Marshal(info, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to serialize request info: %v", err)
}
@@ -205,7 +205,7 @@ func TestRequestEventRequestInfo(t *testing.T) {
t.Fatalf("Failed to resolve request info: %v", err)
}
raw, err := json.Marshal(info)
raw, err := json.Marshal(info, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to serialize request info: %v", err)
}
@@ -308,7 +308,7 @@ func TestRequestInfoClone(t *testing.T) {
// check the original data
// ---
originalRaw, err := json.Marshal(info)
originalRaw, err := json.Marshal(info, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to serialize original request info: %v", err)
}
@@ -321,7 +321,7 @@ func TestRequestInfoClone(t *testing.T) {
// check the clone data
// ---
cloneRaw, err := json.Marshal(clone)
cloneRaw, err := json.Marshal(clone, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to serialize clone request info: %v", err)
}
+16 -16
View File
@@ -3,7 +3,7 @@ package core_test
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -98,7 +98,7 @@ func TestFileFieldPrepareValue(t *testing.T) {
if err != nil {
t.Fatal(err)
}
f1Raw, err := json.Marshal(f1)
f1Raw, err := json.Marshal(f1, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -143,7 +143,7 @@ func TestFileFieldPrepareValue(t *testing.T) {
t.Fatal(err)
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -212,7 +212,7 @@ func TestFileFieldDriverValue(t *testing.T) {
}
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -699,7 +699,7 @@ func TestFileFieldFindGetter(t *testing.T) {
v := getter(record)
raw, err := json.Marshal(v)
raw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -816,7 +816,7 @@ func TestFileFieldFindSetter(t *testing.T) {
setter(record, s.value)
raw, err := json.Marshal(record.Get(s.field.GetName()))
raw, err := json.Marshal(record.Get(s.field.GetName()), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -915,8 +915,8 @@ func TestFileFieldIntercept(t *testing.T) {
tests.TestValidationErrors(t, err, []string{"text"})
raw, _ := json.Marshal(record.GetRaw("file_many"))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3})
raw, _ := json.Marshal(record.GetRaw("file_many"), json.Deterministic(true))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3}, json.Deterministic(true))
if !bytes.Equal(expectedRaw, raw) {
t.Fatalf("Expected file field value\n%s\ngot\n%s", expectedRaw, raw)
}
@@ -935,8 +935,8 @@ func TestFileFieldIntercept(t *testing.T) {
t.Fatalf("Expected save to succeed, got %v", err)
}
raw, _ := json.Marshal(record.GetRaw("file_many"))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3.Name})
raw, _ := json.Marshal(record.GetRaw("file_many"), json.Deterministic(true))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3.Name}, json.Deterministic(true))
if !bytes.Equal(expectedRaw, raw) {
t.Fatalf("Expected file field value\n%s\ngot\n%s", expectedRaw, raw)
}
@@ -956,8 +956,8 @@ func TestFileFieldIntercept(t *testing.T) {
t.Fatalf("Expected save to succeed, got %v", err)
}
raw, _ := json.Marshal(record.GetRaw("file_many"))
expectedRaw, _ := json.Marshal([]any{f3.Name, f4.Name})
raw, _ := json.Marshal(record.GetRaw("file_many"), json.Deterministic(true))
expectedRaw, _ := json.Marshal([]any{f3.Name, f4.Name}, json.Deterministic(true))
if !bytes.Equal(expectedRaw, raw) {
t.Fatalf("Expected file field value\n%s\ngot\n%s", expectedRaw, raw)
}
@@ -1067,8 +1067,8 @@ func TestFileFieldInterceptTx(t *testing.T) {
t.Fatalf("Expected save to succeed, got %v", err)
}
raw, _ := json.Marshal(record.GetRaw("file_many"))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3.Name})
raw, _ := json.Marshal(record.GetRaw("file_many"), json.Deterministic(true))
expectedRaw, _ := json.Marshal([]any{f1.Name, f3.Name}, json.Deterministic(true))
if !bytes.Equal(expectedRaw, raw) {
t.Fatalf("Expected file field value\n%s\ngot\n%s", expectedRaw, raw)
}
@@ -1090,8 +1090,8 @@ func TestFileFieldInterceptTx(t *testing.T) {
t.Fatalf("Expected save to succeed, got %v", err)
}
raw, _ := json.Marshal(record.GetRaw("file_many"))
expectedRaw, _ := json.Marshal([]any{f3.Name, f4.Name})
raw, _ := json.Marshal(record.GetRaw("file_many"), json.Deterministic(true))
expectedRaw, _ := json.Marshal([]any{f3.Name, f4.Name}, json.Deterministic(true))
if !bytes.Equal(expectedRaw, raw) {
t.Fatalf("Expected file field value\n%s\ngot\n%s", expectedRaw, raw)
}
+2 -2
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
@@ -57,7 +57,7 @@ func TestGeoPointFieldPrepareValue(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(v)
raw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+2 -2
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"strings"
@@ -496,7 +496,7 @@ func TestPasswordFieldFindSetter(t *testing.T) {
setter(record, s.value)
raw, err := json.Marshal(record.Get(s.field.GetName()))
raw, err := json.Marshal(record.Get(s.field.GetName()), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+4 -4
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
@@ -119,7 +119,7 @@ func TestRelationFieldPrepareValue(t *testing.T) {
t.Fatal(err)
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -181,7 +181,7 @@ func TestRelationFieldDriverValue(t *testing.T) {
}
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -590,7 +590,7 @@ func TestRelationFieldFindSetter(t *testing.T) {
setter(record, s.value)
raw, err := json.Marshal(record.Get(s.field.GetName()))
raw, err := json.Marshal(record.Get(s.field.GetName()), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+4 -4
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
@@ -119,7 +119,7 @@ func TestSelectFieldPrepareValue(t *testing.T) {
t.Fatal(err)
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -181,7 +181,7 @@ func TestSelectFieldDriverValue(t *testing.T) {
}
}
vRaw, err := json.Marshal(v)
vRaw, err := json.Marshal(v, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -503,7 +503,7 @@ func TestSelectFieldFindSetter(t *testing.T) {
setter(record, s.value)
raw, err := json.Marshal(record.Get(s.field.GetName()))
raw, err := json.Marshal(record.Get(s.field.GetName()), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -2,7 +2,7 @@ package core_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"reflect"
"strings"
"testing"
+4 -4
View File
@@ -2,7 +2,7 @@ package core
import (
"database/sql/driver"
"encoding/json"
"encoding/json/v2"
"fmt"
"slices"
"strconv"
@@ -277,7 +277,7 @@ func (l *FieldsList) add(pos int, newField Field) {
// String returns the string representation of the current list.
func (l FieldsList) String() string {
v, _ := json.Marshal(l)
v, _ := l.MarshalJSON()
return string(v)
}
@@ -355,12 +355,12 @@ func (l FieldsList) MarshalJSON() ([]byte, error) {
wrapper = append(wrapper, data)
}
return json.Marshal(wrapper)
return json.Marshal(wrapper, json.Deterministic(true))
}
// Value implements the [driver.Valuer] interface.
func (l FieldsList) Value() (driver.Value, error) {
data, err := json.Marshal(l)
data, err := l.MarshalJSON()
return string(data), err
}
+1 -1
View File
@@ -2,7 +2,7 @@ package core_test
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"slices"
"strconv"
"strings"
+2 -2
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
"time"
@@ -63,7 +63,7 @@ func TestLogsStats(t *testing.T) {
t.Fatal(err)
}
encoded, _ := json.Marshal(result)
encoded, _ := json.Marshal(result, json.Deterministic(true))
if string(encoded) != expected {
t.Fatalf("Expected\n%q\ngot\n%q", expected, string(encoded))
}
+1 -1
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
"time"
+2 -2
View File
@@ -1,7 +1,7 @@
package core
import (
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -354,7 +354,7 @@ func (r *RecordFieldResolver) resolveStaticRequestField(path ...string) (*search
// if that doesn't work, try encoding it
if castErr != nil {
encoded, jsonErr := json.Marshal(v)
encoded, jsonErr := json.Marshal(v, json.Deterministic(true))
if jsonErr == nil {
val = string(encoded)
}
+2 -2
View File
@@ -1,7 +1,7 @@
package core
import (
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"reflect"
@@ -333,7 +333,7 @@ func (r *runner) processRequestBodyEachModifier(bodyField Field) (*search.Resolv
}
bodyItems := toSlice(r.resolver.requestInfo.Body[bodyField.GetName()])
bodyItemsRaw, err := json.Marshal(bodyItems)
bodyItemsRaw, err := json.Marshal(bodyItems, json.Deterministic(true))
if err != nil {
return nil, fmt.Errorf("cannot serialize the data for field %q", r.activeProps[2])
}
+2 -2
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"regexp"
"slices"
"strings"
@@ -940,7 +940,7 @@ func TestRecordFieldResolverResolveStaticRequestInfoFields(t *testing.T) {
t.Fatalf("Expected parameter r.Identifier %q, got %q", paramName, r.Identifier)
}
encodedParamValue, _ := json.Marshal(paramValue)
encodedParamValue, _ := json.Marshal(paramValue, json.Deterministic(true))
if string(encodedParamValue) != s.expectParamValue {
t.Fatalf("Expected r.Params %#v for %s, got %#v", s.expectParamValue, r.Identifier, string(encodedParamValue))
}
+4 -4
View File
@@ -3,7 +3,7 @@ package core
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"log"
@@ -1218,12 +1218,12 @@ func areValuesEqual(a any, b any) bool {
bv, ok := b.(types.JSONRaw)
return ok && bytes.Equal(av, bv)
default:
aRaw, err := json.Marshal(a)
aRaw, err := json.Marshal(a, json.Deterministic(true))
if err != nil {
return false
}
bRaw, err := json.Marshal(b)
bRaw, err := json.Marshal(b, json.Deterministic(true))
if err != nil {
return false
}
@@ -1324,7 +1324,7 @@ func (record *Record) PublicExport() map[string]any {
//
// Only the data exported by `PublicExport()` will be serialized.
func (m Record) MarshalJSON() ([]byte, error) {
return json.Marshal(m.PublicExport())
return json.Marshal(m.PublicExport(), json.Deterministic(true))
}
// UnmarshalJSON implements the [json.Unmarshaler] interface.
+15 -13
View File
@@ -4,7 +4,7 @@ import (
"bytes"
"context"
"database/sql"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"regexp"
@@ -31,7 +31,7 @@ func TestNewRecord(t *testing.T) {
m := core.NewRecord(collection)
rawData, err := json.Marshal(m.FieldsData()) // should be initialized with the defaults
rawData, err := json.Marshal(m.FieldsData(), json.Deterministic(true)) // should be initialized with the defaults
if err != nil {
t.Fatal(err)
}
@@ -520,7 +520,7 @@ func TestRecordMergeExpand(t *testing.T) {
result := m.Expand()
raw, err := json.Marshal(result)
raw, err := json.Marshal(result, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -566,7 +566,7 @@ func TestRecordMergeExpandNilCheck(t *testing.T) {
m := core.NewRecord(collection)
m.MergeExpand(s.expand)
raw, err := json.Marshal(m)
raw, err := json.Marshal(m, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -663,7 +663,7 @@ func TestRecordFieldsData(t *testing.T) {
m.Set("field2", 456)
m.Set("unknown", 789)
raw, err := json.Marshal(m.FieldsData())
raw, err := json.Marshal(m.FieldsData(), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -691,7 +691,7 @@ func TestRecordCustomData(t *testing.T) {
m.Set("field2", 456)
m.Set("unknown", 789)
raw, err := json.Marshal(m.CustomData())
raw, err := json.Marshal(m.CustomData(), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -1103,14 +1103,16 @@ func TestRecordGetUnsavedFiles(t *testing.T) {
t.Run(fmt.Sprintf("%d_%#v", i, s.key), func(t *testing.T) {
v := record.GetUnsavedFiles(s.key)
raw, err := json.Marshal(v)
raw, err := json.Marshal(v,
json.Deterministic(true),
json.FormatNilSliceAsNull(true),
)
if err != nil {
t.Fatal(err)
}
rawStr := string(raw)
if rawStr != s.expected {
t.Fatalf("Expected\n%s\ngot\n%s", s.expected, rawStr)
if str := string(raw); str != s.expected {
t.Fatalf("Expected\n%s\ngot\n%s", s.expected, str)
}
})
}
@@ -1164,7 +1166,7 @@ func TestRecordUnmarshalJSONField(t *testing.T) {
t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr)
}
raw, _ := json.Marshal(s.destination)
raw, _ := json.Marshal(s.destination, json.Deterministic(true))
if v := string(raw); v != s.expectedJSON {
t.Fatalf("Expected %q, got %q", s.expectedJSON, v)
}
@@ -1271,7 +1273,7 @@ func TestRecordDBExport(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(result)
raw, err := json.Marshal(result, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -1515,7 +1517,7 @@ func TestRecordPublicExportAndMarshalJSON(t *testing.T) {
m.Unhide(s.unhideFields...)
m.Hide(s.hideFields...)
exportResult, err := json.Marshal(m.PublicExport())
exportResult, err := json.Marshal(m.PublicExport(), json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+3 -3
View File
@@ -3,7 +3,7 @@ package core_test
import (
"context"
"database/sql"
"encoding/json"
"encoding/json/v2"
"errors"
"strings"
"testing"
@@ -240,7 +240,7 @@ func TestExpandRecords(t *testing.T) {
t.Errorf("Expected %d failures, got %d\n%v", s.expectExpandFailures, len(failed), failed)
}
encoded, _ := json.Marshal(records)
encoded, _ := json.Marshal(records, json.Deterministic(true))
encodedStr := string(encoded)
totalExpandProps := strings.Count(encodedStr, `"`+core.FieldNameExpand+`":`)
totalEmptyExpands := strings.Count(encodedStr, `"`+core.FieldNameExpand+`":{}`)
@@ -420,7 +420,7 @@ func TestExpandRecord(t *testing.T) {
t.Errorf("Expected %d failures, got %d\n%v", s.expectExpandFailures, len(failed), failed)
}
encoded, _ := json.Marshal(record)
encoded, _ := json.Marshal(record, json.Deterministic(true))
encodedStr := string(encoded)
totalExpandProps := strings.Count(encodedStr, `"`+core.FieldNameExpand+`":`)
totalEmptyExpands := strings.Count(encodedStr, `"`+core.FieldNameExpand+`":{}`)
+3 -3
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"slices"
@@ -107,7 +107,7 @@ func TestRecordQueryOne(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(s.model)
raw, err := json.Marshal(s.model, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -192,7 +192,7 @@ func TestRecordQueryAll(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(s.result)
raw, err := json.Marshal(s.result, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+4 -4
View File
@@ -2,7 +2,7 @@ package core
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"os"
@@ -237,7 +237,7 @@ func (s *Settings) String() string {
s.mu.RLock()
defer s.mu.RUnlock()
raw, _ := json.Marshal(s)
raw, _ := s.MarshalJSON()
return string(raw)
}
@@ -264,7 +264,7 @@ func (s *Settings) DBExport(app App) (map[string]any, error) {
s.settings.SuperuserIPs = []string{}
}
encoded, err := json.Marshal(s.settings)
encoded, err := json.Marshal(s.settings, json.Deterministic(true))
if err != nil {
return nil, err
}
@@ -361,7 +361,7 @@ func (s *Settings) MarshalJSON() ([]byte, error) {
copy.SuperuserIPs = []string{}
}
return json.Marshal(copy)
return json.Marshal(copy, json.Deterministic(true))
}
// -------------------------------------------------------------------
+7 -7
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"os"
"strings"
@@ -112,12 +112,12 @@ func TestSettingsMerge(t *testing.T) {
t.Fatal(err)
}
s1Encoded, err := json.Marshal(s1)
s1Encoded, err := json.Marshal(s1, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
s2Encoded, err := json.Marshal(s2)
s2Encoded, err := json.Marshal(s2, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -138,12 +138,12 @@ func TestSettingsClone(t *testing.T) {
t.Fatal(err)
}
s1Bytes, err := json.Marshal(s1)
s1Bytes, err := json.Marshal(s1, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
s2Bytes, err := json.Marshal(s2)
s2Bytes, err := json.Marshal(s2, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -174,7 +174,7 @@ func TestSettingsMarshalJSON(t *testing.T) {
settings.S3.Secret = testSecret
settings.Backups.S3.Secret = testSecret
raw, err := json.Marshal(settings)
raw, err := json.Marshal(settings, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -228,7 +228,7 @@ func TestSettingsValidate(t *testing.T) {
`"rateLimits":{`,
}
errBytes, _ := json.Marshal(err)
errBytes, _ := json.Marshal(err, json.Deterministic(true))
jsonErr := string(errBytes)
for _, expected := range expectations {
if !strings.Contains(jsonErr, expected) {
+1 -1
View File
@@ -2,7 +2,7 @@ package core
import (
"database/sql"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"os"
+3 -3
View File
@@ -1,7 +1,7 @@
package core_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"slices"
"testing"
@@ -530,7 +530,7 @@ func TestCreateViewFields(t *testing.T) {
}
if len(s.expectFields) != len(result) {
serialized, _ := json.Marshal(result)
serialized, _ := json.Marshal(result, json.Deterministic(true))
t.Fatalf("Expected %d fields, got %d: \n%s", len(s.expectFields), len(result), serialized)
}
@@ -835,7 +835,7 @@ func TestDryRunView(t *testing.T) {
// check fields
// ---
if len(s.expectFields) != len(result.Fields) {
serialized, _ := json.Marshal(result.Fields)
serialized, _ := json.Marshal(result.Fields, json.Deterministic(true))
t.Fatalf("Expected %d fields, got %d: \n%s", len(s.expectFields), len(result.Fields), serialized)
}
for name, typ := range s.expectFields {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/json"
"encoding/json/v2"
"encoding/pem"
"testing"
+1 -1
View File
@@ -2,7 +2,7 @@ package forms_test
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"errors"
"maps"
"os"
+1
View File
@@ -39,6 +39,7 @@ require (
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/testify v1.8.0 // indirect
golang.org/x/mod v0.40.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.41.0 // indirect
+9 -3
View File
@@ -4,8 +4,9 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dlclark/regexp2/v2 v2.5.2 h1:HAsucWRhsqcDzl6Ua9aR8JwYOTzrZyPrF0/FNxJVAI0=
@@ -80,8 +81,11 @@ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
@@ -111,8 +115,10 @@ golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.29.0 h1:CXgwL8cvxmyzBQZzbSl/6xFtMCryb6u8IOqDci39cgc=
modernc.org/cc/v4 v4.29.0/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
+1 -1
View File
@@ -1,7 +1,7 @@
package migrations
import (
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"os"
+1 -1
View File
@@ -8,7 +8,7 @@ package ghupdate
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
+5 -5
View File
@@ -3,7 +3,7 @@ package jsvm
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"io"
"io/fs"
@@ -352,7 +352,7 @@ func BindCore(vm *goja.Runtime) {
}
// as a last attempt try to json encode the value
rawBytes, _ := json.Marshal(raw)
rawBytes, _ := json.Marshal(raw, json.Deterministic(true))
return rawBytes, nil
}
@@ -381,7 +381,7 @@ func BindCore(vm *goja.Runtime) {
}
// as a last attempt try to json encode the value
rawBytes, _ := json.Marshal(raw)
rawBytes, _ := json.Marshal(raw, json.Deterministic(true))
return string(rawBytes), nil
}
@@ -1217,13 +1217,13 @@ func newDynamicModel(shape map[string]any) any {
case reflect.Map:
raw, _ := json.Marshal(v)
newV := types.JSONMap[any]{}
newV.Scan(raw)
_ = newV.Scan(raw)
v = newV
vt = reflect.TypeOf(v)
case reflect.Slice, reflect.Array:
raw, _ := json.Marshal(v)
newV := types.JSONArray[any]{}
newV.Scan(raw)
_ = newV.Scan(raw)
v = newV
vt = reflect.TypeOf(newV)
case reflect.Pointer:
+5 -5
View File
@@ -2,7 +2,7 @@ package jsvm
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
@@ -505,12 +505,12 @@ func TestBindCoreMailerMessage(t *testing.T) {
t.Fatalf("Expected mailer.Message, got %v", m)
}
raw, err := json.Marshal(m)
raw, err := json.Marshal(m, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
expected := `{"from":{"Name":"test_from","Address":"test_from@example.com"},"to":[{"Name":"test_to1","Address":"test_to1@example.com"},{"Name":"test_to2","Address":"test_to2@example.com"}],"bcc":[{"Name":"test_bcc1","Address":"test_bcc1@example.com"},{"Name":"test_bcc2","Address":"test_bcc2@example.com"}],"cc":[{"Name":"test_cc1","Address":"test_cc1@example.com"},{"Name":"test_cc2","Address":"test_cc2@example.com"}],"subject":"test_subject","html":"test_html","text":"test_text","headers":{"header1":"a","header2":"b"},"attachments":null,"inlineAttachments":null}`
expected := `{"from":{"Name":"test_from","Address":"test_from@example.com"},"to":[{"Name":"test_to1","Address":"test_to1@example.com"},{"Name":"test_to2","Address":"test_to2@example.com"}],"bcc":[{"Name":"test_bcc1","Address":"test_bcc1@example.com"},{"Name":"test_bcc2","Address":"test_bcc2@example.com"}],"cc":[{"Name":"test_cc1","Address":"test_cc1@example.com"},{"Name":"test_cc2","Address":"test_cc2@example.com"}],"subject":"test_subject","html":"test_html","text":"test_text","headers":{"header1":"a","header2":"b"},"attachments":{},"inlineAttachments":{}}`
if string(raw) != expected {
t.Fatalf("Expected \n%s, \ngot \n%s", expected, raw)
@@ -1178,7 +1178,7 @@ func TestBindApisErrors(t *testing.T) {
t.Errorf("[%s] Expected Message %q, got %q", s.js, s.expectMessage, apiErr.Message)
}
dataRaw, _ := json.Marshal(apiErr.RawData())
dataRaw, _ := json.Marshal(apiErr.RawData(), json.Deterministic(true))
if string(dataRaw) != s.expectData {
t.Errorf("[%s] Expected Data %q, got %q", s.js, s.expectData, dataRaw)
}
@@ -1439,7 +1439,7 @@ func TestBindHTTPSend(t *testing.T) {
res.Header().Add("X-Custom", "custom_header")
res.Header().Add("Set-Cookie", "sessionId=123456")
infoRaw, _ := json.Marshal(info)
infoRaw, _ := json.Marshal(info, json.Deterministic(true))
// write back the submitted request
res.Write(infoRaw)
+2 -2
View File
@@ -2,7 +2,7 @@ package jsvm
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"strings"
"testing"
@@ -166,7 +166,7 @@ func TestFormDataEntries(t *testing.T) {
entries := data.Entries()
rawEntries, err := json.Marshal(entries)
rawEntries, err := json.Marshal(entries, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+11 -11
View File
@@ -93,12 +93,12 @@ migrate((app) => {
"type": "text"
},
{
"exceptDomains": null,
"exceptDomains": [],
"help": "",
"hidden": false,
"id": "email@TEST_RANDOM",
"name": "email",
"onlyDomains": null,
"onlyDomains": [],
"presentable": false,
"required": true,
"system": true,
@@ -200,7 +200,7 @@ migrate((app) => {
package _test_migrations
import (
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
@@ -275,12 +275,12 @@ func init() {
"type": "text"
},
{
"exceptDomains": null,
"exceptDomains": [],
"help": "",
"hidden": false,
"id": "email@TEST_RANDOM",
"name": "email",
"onlyDomains": null,
"onlyDomains": [],
"presentable": false,
"required": true,
"system": true,
@@ -546,12 +546,12 @@ migrate((app) => {
"type": "text"
},
{
"exceptDomains": null,
"exceptDomains": [],
"help": "",
"hidden": false,
"id": "email3885137012",
"name": "email",
"onlyDomains": null,
"onlyDomains": [],
"presentable": false,
"required": true,
"system": true,
@@ -649,7 +649,7 @@ migrate((app) => {
package _test_migrations
import (
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
@@ -731,12 +731,12 @@ func init() {
"type": "text"
},
{
"exceptDomains": null,
"exceptDomains": [],
"help": "",
"hidden": false,
"id": "email3885137012",
"name": "email",
"onlyDomains": null,
"onlyDomains": [],
"presentable": false,
"required": true,
"system": true,
@@ -1041,7 +1041,7 @@ migrate((app) => {
package _test_migrations
import (
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
+12 -7
View File
@@ -2,7 +2,8 @@ package migratecmd
import (
"bytes"
"encoding/json"
"encoding/json/jsontext"
"encoding/json/v2"
"errors"
"fmt"
"path/filepath"
@@ -383,7 +384,7 @@ func (p *plugin) goCreateTemplate(collection *core.Collection) (string, error) {
const template = `package %s
import (
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
@@ -436,7 +437,7 @@ func (p *plugin) goDeleteTemplate(collection *core.Collection) (string, error) {
const template = `package %s
import (
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
@@ -621,7 +622,7 @@ func (p *plugin) goDiffTemplate(new *core.Collection, old *core.Collection) (str
if strings.Contains(combined, "json.Unmarshal(") ||
strings.Contains(combined, "json.Marshal(") {
imports += "\n\t\"encoding/json\"\n"
imports += "\n\t\"encoding/json/v2\"\n"
}
imports += "\n\t\"github.com/pocketbase/pocketbase/core\""
@@ -666,7 +667,11 @@ func init() {
}
func marhshalWithoutEscape(v any, prefix string, indent string) ([]byte, error) {
raw, err := json.MarshalIndent(v, prefix, indent)
raw, err := json.Marshal(v,
json.Deterministic(true),
jsontext.WithIndentPrefix(prefix),
jsontext.WithIndent(indent),
)
if err != nil {
return nil, err
}
@@ -720,8 +725,8 @@ func diffMaps(old, new map[string]any, excludeKeys ...string) map[string]any {
}
// compare the serialized version of the values in case of slice or other custom type
rawOld, _ := json.Marshal(vOld)
rawNew, _ := json.Marshal(vNew)
rawOld, _ := json.Marshal(vOld, json.Deterministic(true))
rawNew, _ := json.Marshal(vNew, json.Deterministic(true))
if !bytes.Equal(rawOld, rawNew) {
// if both are maps add recursively only the changed fields
+6 -4
View File
@@ -3,7 +3,7 @@ package tests
import (
"bytes"
"context"
"encoding/json"
"encoding/json/jsontext"
"fmt"
"io"
"maps"
@@ -259,14 +259,16 @@ func (scenario *ApiScenario) test(t testing.TB) {
}
} else {
// normalize json response format
buffer := new(bytes.Buffer)
err := json.Compact(buffer, recorder.Body.Bytes())
var normalizedBody string
buf := new(bytes.Buffer)
enc := jsontext.NewEncoder(buf)
err := enc.WriteValue(recorder.Body.Bytes())
if err != nil {
// not a json...
normalizedBody = recorder.Body.String()
} else {
normalizedBody = buffer.String()
normalizedBody = buf.String()
}
for _, item := range scenario.ExpectedContent {
+1 -1
View File
@@ -48,7 +48,7 @@ func TestCreateSuccess(t *testing.T) {
t.Fatalf("Expected zip with name %q, got %q", zipName, name)
}
expectedSize := int64(544)
expectedSize := int64(532)
if size := info.Size(); size != expectedSize {
t.Fatalf("Expected zip with size %d, got %d", expectedSize, size)
}
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
+3 -3
View File
@@ -3,7 +3,7 @@ package auth
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"testing"
"golang.org/x/oauth2"
@@ -215,12 +215,12 @@ func TestExtra(t *testing.T) {
after := b.Extra()
rawExtra, err := json.Marshal(extra)
rawExtra, err := json.Marshal(extra, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
rawAfter, err := json.Marshal(after)
rawAfter, err := json.Marshal(after, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"io"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"fmt"
"github.com/pocketbase/pocketbase/tools/types"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"fmt"
"github.com/pocketbase/pocketbase/tools/types"
+8 -6
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
@@ -53,12 +53,14 @@ func (p *Facebook) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
}
extracted := struct {
Id string
Name string
Email string
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Picture struct {
Data struct{ Url string }
}
Data struct {
Url string `json:"url"`
} `json:"data"`
} `json:"picture"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
+4 -4
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
@@ -119,9 +119,9 @@ func (p *Gitea) fetchVerifiedPrimaryEmail(token *oauth2.Token) (string, error) {
}
emails := []struct {
Email string
Verified bool
Primary bool
Email string `json:"email"`
Verified bool `json:"verified"`
Primary bool `json:"primary"`
}{}
if err := json.Unmarshal(content, &emails); err != nil {
return "", err
+4 -4
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"io"
"strconv"
@@ -120,9 +120,9 @@ func (p *Gitee) fetchPrimaryEmail(token *oauth2.Token) (string, error) {
}
emails := []struct {
Email string
State string
Scope []string
Email string `json:"email"`
State string `json:"state"`
Scope []string `json:"scope"`
}{}
if err := json.Unmarshal(content, &emails); err != nil {
// ignore unmarshal error in case "Keep my email address private"
+4 -4
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"io"
"strconv"
@@ -116,9 +116,9 @@ func (p *Github) fetchVerifiedPrimaryEmail(token *oauth2.Token) (string, error)
}
emails := []struct {
Email string
Verified bool
Primary bool
Email string `json:"email"`
Verified bool `json:"verified"`
Primary bool `json:"primary"`
}{}
if err := json.Unmarshal(content, &emails); err != nil {
return "", err
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"strconv"
"time"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"crypto/ed25519"
"crypto/rsa"
"encoding/base64"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
@@ -105,7 +105,7 @@ func Fetch(ctx context.Context, jwksURL string, kid string) (*JWK, error) {
}
jwks := struct {
Keys []*JWK
Keys []*JWK `json:"keys"`
}{}
err = json.Unmarshal(rawBody, &jwks)
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"crypto/rand"
"crypto/rsa"
"encoding/base64"
"encoding/json"
"encoding/json/v2"
"fmt"
"math/big"
"net/http"
@@ -252,7 +252,7 @@ func TestValidateTokenSignature(t *testing.T) {
}
server := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
_ = json.NewEncoder(res).Encode(map[string]any{"keys": []*jwk.JWK{
_ = json.MarshalWrite(res, map[string]any{"keys": []*jwk.JWK{
{
Kid: "key1",
Kty: "OKP",
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"strconv"
"github.com/pocketbase/pocketbase/tools/types"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+1 -2
View File
@@ -3,7 +3,7 @@ package auth
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
@@ -68,7 +68,6 @@ func (p *Linear) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
} `json:"viewer"`
} `json:"data"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
}
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"strings"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"slices"
+1 -1
View File
@@ -3,7 +3,7 @@ package auth
import (
"bytes"
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"net/http"
"github.com/pocketbase/pocketbase/tools/types"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"os"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+2 -2
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"github.com/pocketbase/pocketbase/tools/types"
@@ -62,7 +62,7 @@ func (p *Planningcenter) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
// don't map the email because users can have multiple assigned
// and it's not clear if they are verified
}
}
} `json:"data"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"strconv"
"github.com/pocketbase/pocketbase/tools/types"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"net/http"
"github.com/pocketbase/pocketbase/tools/types"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"net/http"
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+1 -2
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"strconv"
@@ -69,7 +69,6 @@ func (p *VK) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
AvatarURL string `json:"photo_max"`
} `json:"response"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
}
+1 -2
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
@@ -62,7 +62,6 @@ func (p *Wakatime) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
IsEmailConfirmed bool `json:"is_email_confirmed"`
} `json:"data"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
}
+1 -1
View File
@@ -2,7 +2,7 @@ package auth
import (
"context"
"encoding/json"
"encoding/json/v2"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
+2 -2
View File
@@ -1,7 +1,7 @@
package cron
import (
"encoding/json"
"encoding/json/v2"
"slices"
"sync"
"testing"
@@ -128,7 +128,7 @@ func TestCronAddAndRemove(t *testing.T) {
"test5": `{"minutes":{"1":{}},"hours":{"2":{}},"days":{"3":{}},"months":{"4":{}},"daysOfWeek":{"5":{}}}`,
}
for k, v := range expectedSchedules {
raw, err := json.Marshal(indexedJobs[k].schedule)
raw, err := json.Marshal(indexedJobs[k].schedule, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -1,6 +1,6 @@
package cron
import "encoding/json"
import "encoding/json/v2"
// Job defines a single registered cron job.
type Job struct {
+2 -2
View File
@@ -1,7 +1,7 @@
package cron
import (
"encoding/json"
"encoding/json/v2"
"testing"
)
@@ -59,7 +59,7 @@ func TestJobMarshalJSON(t *testing.T) {
j := Job{id: "test_id", schedule: s}
raw, err := json.Marshal(j)
raw, err := json.Marshal(j, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
+2 -2
View File
@@ -1,7 +1,7 @@
package cron_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"
"time"
@@ -265,7 +265,7 @@ func TestNewSchedule(t *testing.T) {
return
}
encoded, err := json.Marshal(schedule)
encoded, err := json.Marshal(schedule, json.Deterministic(true))
if err != nil {
t.Fatalf("Failed to marshalize the result schedule: %v", err)
}
+1 -1
View File
@@ -2,7 +2,7 @@ package dbutils_test
import (
"bytes"
"encoding/json"
"encoding/json/v2"
"fmt"
"strings"
"testing"
+2 -2
View File
@@ -64,8 +64,8 @@ func TestNewFileFromPath(t *testing.T) {
if match, err := regexp.Match(normalizedNamePattern, []byte(f.Name)); !match {
t.Fatalf("Expected Name to match %v, got %q (%v)", normalizedNamePattern, f.Name, err)
}
if f.Size != 73 {
t.Fatalf("Expected Size %v, got %v", 73, f.Size)
if f.Size != 77 {
t.Fatalf("Expected Size %v, got %v", 77, f.Size)
}
if _, ok := f.Reader.(*filesystem.PathReader); !ok {
t.Fatalf("Expected Reader to be PathReader, got %v", f.Reader)
+5 -5
View File
@@ -444,7 +444,7 @@ func TestFilesystemServe(t *testing.T) {
map[string]string{
"Content-Disposition": `inline; filename="test_name.png"`,
"Content-Type": "image/png",
"Content-Length": "73",
"Content-Length": "77",
"Content-Security-Policy": csp,
"Cache-Control": cacheControl,
},
@@ -459,7 +459,7 @@ func TestFilesystemServe(t *testing.T) {
map[string]string{
"Content-Disposition": `attachment; filename="test_name_download.png"`,
"Content-Type": "image/png",
"Content-Length": "73",
"Content-Length": "77",
"Content-Security-Policy": csp,
"Cache-Control": cacheControl,
},
@@ -792,8 +792,8 @@ func TestFilesystemCopy(t *testing.T) {
}
defer f.Close()
if f.Size() != 73 {
t.Fatalf("Expected file size %d, got %d", 73, f.Size())
if f.Size() != 77 {
t.Fatalf("Expected file size %d, got %d", 77, f.Size())
}
}
@@ -895,7 +895,7 @@ func TestFilesystemServeSingleRange(t *testing.T) {
t.Fatalf("Expected StatusCode %d, got %d", http.StatusPartialContent, result.StatusCode)
}
expectedRange := "bytes 0-20/73"
expectedRange := "bytes 0-20/77"
if cr := result.Header.Get("Content-Range"); cr != expectedRange {
t.Fatalf("Expected Content-Range %q, got %q", expectedRange, cr)
}
+6 -3
View File
@@ -1,7 +1,7 @@
package fileblob
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"os"
)
@@ -50,7 +50,8 @@ func setAttrs(path string, xa xattrs) error {
return err
}
if err := json.NewEncoder(f).Encode(xa); err != nil {
err = json.MarshalWrite(f, xa)
if err != nil {
f.Close()
os.Remove(f.Name())
return err
@@ -75,7 +76,9 @@ func getAttrs(path string) (xattrs, error) {
}
xa := new(xattrs)
if err := json.NewDecoder(f).Decode(xa); err != nil {
err = json.UnmarshalRead(f, xa)
if err != nil {
f.Close()
return xattrs{}, err
}
@@ -1,7 +1,7 @@
package s3_test
import (
"encoding/json"
"encoding/json/v2"
"encoding/xml"
"testing"
@@ -29,7 +29,7 @@ func TestResponseErrorSerialization(t *testing.T) {
t.Fatal(err)
}
jsonRaw, err := json.Marshal(respErr)
jsonRaw, err := json.Marshal(respErr, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -2,7 +2,7 @@ package s3_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"io"
"net/http"
"strings"
@@ -78,7 +78,7 @@ func TestS3GetObject(t *testing.T) {
}
// check serialized attributes
raw, err := json.Marshal(resp)
raw, err := json.Marshal(resp, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -2,7 +2,7 @@ package s3_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"net/http"
"testing"
@@ -63,7 +63,7 @@ func TestS3HeadObject(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(resp)
raw, err := json.Marshal(resp, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -2,7 +2,7 @@ package s3_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"io"
"net/http"
"strings"
@@ -143,7 +143,7 @@ func TestS3ListObjects(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(resp)
raw, err := json.Marshal(resp, json.Deterministic(true))
if err != nil {
t.Fatal(err)
}
@@ -2,7 +2,7 @@ package s3blob_test
import (
"context"
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
@@ -261,7 +261,11 @@ func TestDriverAttributes(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(attrs)
raw, err := json.Marshal(
attrs,
json.Deterministic(true),
json.FormatNilSliceAsNull(true),
)
if err != nil {
t.Fatal(err)
}
@@ -362,7 +366,11 @@ func TestDriverListPaged(t *testing.T) {
t.Fatal(err)
}
raw, err := json.Marshal(page)
raw, err := json.Marshal(
page,
json.Deterministic(true),
json.FormatNilSliceAsNull(true),
)
if err != nil {
t.Fatal(err)
}
@@ -510,7 +518,11 @@ func TestDriverNewRangeReader(t *testing.T) {
}
}
rawAttrs, err := json.Marshal(r.Attributes())
rawAttrs, err := json.Marshal(
r.Attributes(),
json.Deterministic(true),
json.FormatNilSliceAsNull(true),
)
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -1,7 +1,7 @@
package list
import (
"encoding/json"
"encoding/json/v2"
"regexp"
"strings"
+1 -1
View File
@@ -1,7 +1,7 @@
package list_test
import (
"encoding/json"
"encoding/json/v2"
"fmt"
"testing"

Some files were not shown because too many files have changed in this diff Show More