diff --git a/go.mod b/go.mod
index b6c65be..79bb207 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.18
require (
github.com/Masterminds/sprig/v3 v3.2.2
github.com/hashicorp/hcl/v2 v2.12.0
+ github.com/imdario/mergo v0.3.13
github.com/pkg/errors v0.9.1
github.com/urfave/cli/v2 v2.4.0
github.com/zclconf/go-cty v1.8.0
@@ -18,7 +19,6 @@ require (
github.com/google/go-cmp v0.3.1 // indirect
github.com/google/uuid v1.1.1 // indirect
github.com/huandu/xstrings v1.3.1 // indirect
- github.com/imdario/mergo v0.3.11 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
@@ -34,5 +34,5 @@ require (
github.com/go-chi/chi v1.5.4
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
+ gopkg.in/yaml.v3 v3.0.1
)
diff --git a/go.sum b/go.sum
index 5b99ef9..d37f5a6 100644
--- a/go.sum
+++ b/go.sum
@@ -31,8 +31,9 @@ github.com/hashicorp/hcl/v2 v2.12.0 h1:PsYxySWpMD4KPaoJLnsHwtK5Qptvj/4Q6s0t4sUxZ
github.com/hashicorp/hcl/v2 v2.12.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -100,5 +101,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/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=
diff --git a/internal/command/check.go b/internal/command/check.go
new file mode 100644
index 0000000..6b619e3
--- /dev/null
+++ b/internal/command/check.go
@@ -0,0 +1,49 @@
+package command
+
+import (
+ "fmt"
+
+ "github.com/pkg/errors"
+ "github.com/santhosh-tekuri/jsonschema/v5"
+ _ "github.com/santhosh-tekuri/jsonschema/v5/httploader"
+ "github.com/urfave/cli/v2"
+)
+
+func Check() *cli.Command {
+ flags := []cli.Flag{}
+
+ flags = append(flags, commonFlags()...)
+
+ return &cli.Command{
+ Name: "check",
+ Usage: "Check values with the given schema",
+ Flags: flags,
+ Action: func(ctx *cli.Context) error {
+ schema, err := loadSchema(ctx)
+ if err != nil {
+ return errors.Wrap(err, "could not load schema")
+ }
+
+ _, values, err := loadData(ctx)
+ if err != nil {
+ return errors.Wrap(err, "could not load data")
+ }
+
+ if err := schema.Validate(values); err != nil {
+ if _, ok := err.(*jsonschema.ValidationError); ok {
+ fmt.Printf("%#v\n", err)
+
+ return errors.New("invalid values")
+ }
+
+ return errors.Wrap(err, "could not validate values")
+ }
+
+ if err := outputValues(ctx, values); err != nil {
+ return errors.Wrap(err, "could not output updated values")
+ }
+
+ return nil
+ },
+ }
+}
diff --git a/internal/command/check_test.go b/internal/command/check_test.go
new file mode 100644
index 0000000..49f0e7b
--- /dev/null
+++ b/internal/command/check_test.go
@@ -0,0 +1,87 @@
+package command
+
+import (
+ "flag"
+ "testing"
+
+ "github.com/pkg/errors"
+ "github.com/urfave/cli/v2"
+)
+
+type ExpectFunc func(t *testing.T, cmd *cli.Command, err error)
+
+type checkCommandTestCase struct {
+ Name string
+ SchemaFile string
+ DefaultFile string
+ ValuesFile string
+ Expect ExpectFunc
+}
+
+var checkCommandTestCases = []checkCommandTestCase{
+ {
+ Name: "ok",
+ SchemaFile: "file://testdata/check/schema.json",
+ DefaultFile: "file://testdata/check/defaults.json",
+ ValuesFile: "file://testdata/check/values-ok.json",
+ Expect: expectNoError,
+ },
+ {
+ Name: "nok",
+ SchemaFile: "file://testdata/check/schema.json",
+ DefaultFile: "file://testdata/check/defaults.json",
+ ValuesFile: "file://testdata/check/values-nok.json",
+ Expect: expectError,
+ },
+}
+
+func TestCheck(t *testing.T) {
+ t.Parallel()
+
+ for _, tc := range checkCommandTestCases {
+ func(tc *checkCommandTestCase) {
+ t.Run(tc.Name, func(t *testing.T) {
+ t.Parallel()
+
+ flags := flag.NewFlagSet("", flag.ExitOnError)
+ cmd := Check()
+
+ for _, f := range cmd.Flags {
+ if err := f.Apply(flags); err != nil {
+ t.Fatal(errors.WithStack(err))
+ }
+ }
+
+ err := flags.Parse([]string{
+ "check",
+ "--schema", tc.SchemaFile,
+ "--defaults", tc.DefaultFile,
+ "--values", tc.ValuesFile,
+ "--output", "null://local?format=json",
+ })
+ if err != nil {
+ t.Fatal(errors.WithStack(err))
+ }
+
+ app := cli.NewApp()
+ ctx := cli.NewContext(app, flags, nil)
+
+ err = cmd.Run(ctx)
+
+ tc.Expect(t, cmd, err)
+ })
+ }(&tc)
+ }
+}
+
+func expectNoError(t *testing.T, cmd *cli.Command, err error) {
+ if err != nil {
+ t.Error(errors.Wrap(err, "the command result in an unexpected error"))
+ }
+}
+
+func expectError(t *testing.T, cmd *cli.Command, err error) {
+ if err == nil {
+ t.Error(errors.New("an error should have been returned"))
+ }
+}
diff --git a/internal/command/common.go b/internal/command/common.go
index 8713f95..5ce3643 100644
--- a/internal/command/common.go
+++ b/internal/command/common.go
@@ -5,6 +5,7 @@ import (
"io"
"net/url"
"os"
+ "reflect"
encjson "encoding/json"
@@ -20,6 +21,7 @@ import (
"forge.cadoles.com/wpetit/formidable/internal/data/updater/null"
"forge.cadoles.com/wpetit/formidable/internal/data/updater/stdout"
"forge.cadoles.com/wpetit/formidable/internal/def"
+ "forge.cadoles.com/wpetit/formidable/internal/merge"
"github.com/pkg/errors"
"github.com/santhosh-tekuri/jsonschema/v5"
"github.com/urfave/cli/v2"
@@ -113,6 +115,46 @@ func loadDefaults(ctx *cli.Context) (interface{}, error) {
return defaults, nil
}
+func loadData(ctx *cli.Context) (defaults interface{}, values interface{}, err error) {
+ values, err = loadValues(ctx)
+ if err != nil {
+ return nil, nil, errors.Wrap(err, "could not load values")
+ }
+
+ defaults, err = loadDefaults(ctx)
+ if err != nil {
+ return nil, nil, errors.Wrap(err, "could not load defaults")
+ }
+
+ merged, err := getMatchingZeroValue(values)
+ if err != nil {
+ return nil, nil, errors.WithStack(err)
+ }
+
+ if defaults != nil {
+ if err := merge.Merge(&merged, defaults, values); err != nil {
+ return nil, nil, errors.Wrap(err, "could not merge values")
+ }
+
+ values = merged
+ }
+
+ return defaults, values, nil
+}
+
+func getMatchingZeroValue(values interface{}) (interface{}, error) {
+ valuesKind := reflect.TypeOf(values).Kind()
+
+ switch valuesKind {
+ case reflect.Map:
+ return make(map[string]interface{}, 0), nil
+ case reflect.Slice:
+ return make([]interface{}, 0), nil
+ default:
+ return nil, errors.Errorf("unexpected type '%T'", values)
+ }
+}
+
func loadSchema(ctx *cli.Context) (*jsonschema.Schema, error) {
schemaFlag := ctx.String("schema")
diff --git a/internal/command/edit.go b/internal/command/edit.go
index e1b147c..6df6db4 100644
--- a/internal/command/edit.go
+++ b/internal/command/edit.go
@@ -55,14 +55,9 @@ func Edit() *cli.Command {
return errors.Wrap(err, "could not load schema")
}
- values, err := loadValues(ctx)
+ defaults, values, err := loadData(ctx)
if err != nil {
- return errors.Wrap(err, "could not load values")
- }
-
- defaults, err := loadDefaults(ctx)
- if err != nil {
- return errors.Wrap(err, "could not load defaults")
+ return errors.Wrap(err, "could not load data")
}
srvCtx, srvCancel := context.WithCancel(ctx.Context)
diff --git a/internal/command/get.go b/internal/command/get.go
index cb966fd..0e82817 100644
--- a/internal/command/get.go
+++ b/internal/command/get.go
@@ -26,9 +26,9 @@ func Get() *cli.Command {
return errors.Wrap(err, "could not load schema")
}
- values, err := loadValues(ctx)
+ _, values, err := loadData(ctx)
if err != nil {
- return errors.Wrap(err, "could not load values")
+ return errors.Wrap(err, "could not load data")
}
if err := schema.Validate(values); err != nil {
diff --git a/internal/command/root.go b/internal/command/root.go
index 0cafced..86b65dd 100644
--- a/internal/command/root.go
+++ b/internal/command/root.go
@@ -8,5 +8,6 @@ func Root() []*cli.Command {
Set(),
Get(),
Delete(),
+ Check(),
}
}
diff --git a/internal/command/set.go b/internal/command/set.go
index 7806f09..d16f0ca 100644
--- a/internal/command/set.go
+++ b/internal/command/set.go
@@ -33,9 +33,9 @@ func Set() *cli.Command {
return errors.Wrap(err, "could not load schema")
}
- values, err := loadValues(ctx)
+ _, values, err := loadData(ctx)
if err != nil {
- return errors.Wrap(err, "could not load values")
+ return errors.Wrap(err, "could not load data")
}
rawPointer := ctx.Args().Get(0)
diff --git a/internal/command/testdata/check/defaults.json b/internal/command/testdata/check/defaults.json
new file mode 100644
index 0000000..536fcc5
--- /dev/null
+++ b/internal/command/testdata/check/defaults.json
@@ -0,0 +1,5 @@
+{
+ "foo": {
+ "bar": "test"
+ }
+}
\ No newline at end of file
diff --git a/internal/command/testdata/check/schema.json b/internal/command/testdata/check/schema.json
new file mode 100644
index 0000000..a6f39f4
--- /dev/null
+++ b/internal/command/testdata/check/schema.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema",
+ "type": "object",
+ "properties": {
+ "foo": {
+ "type": "object",
+ "properties": {
+ "bar": {
+ "type": "string"
+ }
+ },
+ "required": ["bar"]
+ }
+ },
+ "required": ["foo"],
+ "additionalProperties": true
+}
\ No newline at end of file
diff --git a/internal/command/testdata/check/values-nok.json b/internal/command/testdata/check/values-nok.json
new file mode 100644
index 0000000..1ae31ac
--- /dev/null
+++ b/internal/command/testdata/check/values-nok.json
@@ -0,0 +1,5 @@
+{
+ "foo": {
+ "bar": false
+ }
+}
\ No newline at end of file
diff --git a/internal/command/testdata/check/values-ok.json b/internal/command/testdata/check/values-ok.json
new file mode 100644
index 0000000..73cd85a
--- /dev/null
+++ b/internal/command/testdata/check/values-ok.json
@@ -0,0 +1,3 @@
+{
+ "test": 1
+}
\ No newline at end of file
diff --git a/internal/jsonpointer/delete_test.go b/internal/jsonpointer/delete_test.go
index 7ba235e..88730fe 100644
--- a/internal/jsonpointer/delete_test.go
+++ b/internal/jsonpointer/delete_test.go
@@ -33,7 +33,12 @@ func TestPointerDelete(t *testing.T) {
{
"nestedObject": {
"foo": [
- "bar"
+ "bar",
+ {
+ "prop1": {
+ "subProp": 1
+ }
+ }
]
}
}`,
@@ -45,7 +50,8 @@ func TestPointerDelete(t *testing.T) {
{
"nestedObject": {
"foo": [
- "bar"
+ "bar",
+ 0
]
}
}`,
diff --git a/internal/jsonpointer/set_test.go b/internal/jsonpointer/set_test.go
index 9043cbb..61ce556 100644
--- a/internal/jsonpointer/set_test.go
+++ b/internal/jsonpointer/set_test.go
@@ -14,7 +14,9 @@ import (
type pointerSetTestCase struct {
DocPath string
Pointer string
+ Force bool
Value interface{}
+ ExpectedError error
ExpectedRawDocument string
}
@@ -37,7 +39,12 @@ func TestPointerSet(t *testing.T) {
"nestedObject": {
"foo": [
"bar",
- "test"
+ "test",
+ {
+ "prop1": {
+ "subProp": 1
+ }
+ }
]
}
}`,
@@ -52,11 +59,44 @@ func TestPointerSet(t *testing.T) {
"foo": [
"bar",
0,
+ {
+ "prop1": {
+ "subProp": 1
+ }
+ },
"baz"
]
}
}`,
},
+ {
+ DocPath: "./testdata/set/nested.json",
+ Pointer: "/nestedObject/foo/2/prop2",
+ Value: "baz",
+ Force: true,
+ ExpectedRawDocument: `
+ {
+ "nestedObject": {
+ "foo": [
+ "bar",
+ 0,
+ {
+ "prop2": "baz",
+ "prop1": {
+ "subProp": 1
+ }
+ }
+ ]
+ }
+ }`,
+ },
+ {
+ DocPath: "./testdata/set/nested.json",
+ Pointer: "/nestedObject/foo/2/prop2",
+ Value: "baz",
+ Force: false,
+ ExpectedError: ErrNotFound,
+ },
}
for i, tc := range testCases {
@@ -77,8 +117,19 @@ func TestPointerSet(t *testing.T) {
pointer := New(tc.Pointer)
- updatedDoc, err := pointer.Set(baseDoc, tc.Value)
- if err != nil {
+ var updatedDoc interface{}
+
+ if tc.Force {
+ updatedDoc, err = pointer.Force(baseDoc, tc.Value)
+ } else {
+ updatedDoc, err = pointer.Set(baseDoc, tc.Value)
+ }
+
+ if tc.ExpectedError != nil && !errors.Is(err, tc.ExpectedError) {
+ t.Fatalf("Expected error '%v', got '%v'", tc.ExpectedError, errors.Cause(err))
+ }
+
+ if tc.ExpectedError == nil && err != nil {
t.Fatal(errors.WithStack(err))
}
@@ -89,12 +140,20 @@ func TestPointerSet(t *testing.T) {
var expectedDoc interface{}
+ if tc.ExpectedRawDocument == "" {
+ return
+ }
+
if err := json.Unmarshal([]byte(tc.ExpectedRawDocument), &expectedDoc); err != nil {
t.Fatal(errors.WithStack(err))
}
if !reflect.DeepEqual(expectedDoc, updatedDoc) {
- t.Errorf("Set pointer '%s' -> '%v': expected document '%s', got '%s'", tc.Pointer, tc.Value, strings.TrimSpace(tc.ExpectedRawDocument), rawDoc)
+ command := "Set"
+ if tc.Force {
+ command = "Force"
+ }
+ t.Errorf("%s pointer '%s' -> '%v': expected document '%s', got '%s'", command, tc.Pointer, tc.Value, strings.TrimSpace(tc.ExpectedRawDocument), rawDoc)
}
})
}(i, tc)
diff --git a/internal/jsonpointer/testdata/set/nested.json b/internal/jsonpointer/testdata/set/nested.json
index ee92d8f..d153850 100644
--- a/internal/jsonpointer/testdata/set/nested.json
+++ b/internal/jsonpointer/testdata/set/nested.json
@@ -2,7 +2,12 @@
"nestedObject": {
"foo": [
"bar",
- 0
+ 0,
+ {
+ "prop1": {
+ "subProp": 1
+ }
+ }
]
}
}
\ No newline at end of file
diff --git a/internal/merge/merge.go b/internal/merge/merge.go
new file mode 100644
index 0000000..de30898
--- /dev/null
+++ b/internal/merge/merge.go
@@ -0,0 +1,91 @@
+package merge
+
+import (
+ "reflect"
+
+ "github.com/imdario/mergo"
+ "github.com/pkg/errors"
+)
+
+var (
+ ErrNonPointerDst = errors.New("dst is not a pointer")
+ ErrUnsupportedMerge = errors.New("unsupported merge")
+ ErrUnexpectedFailedCast = errors.New("unexpected failed cast")
+)
+
+func Merge(dst interface{}, sources ...interface{}) error {
+ if reflect.TypeOf(dst).Kind() != reflect.Ptr {
+ return errors.WithStack(ErrNonPointerDst)
+ }
+
+ dstPointedKind := reflect.Indirect(reflect.ValueOf(dst)).Elem().Kind()
+
+ for _, src := range sources {
+ srcKind := reflect.ValueOf(src).Kind()
+
+ switch dstPointedKind {
+ case reflect.Map:
+ if srcKind != dstPointedKind {
+ return errors.WithStack(unsupportedMergeError(dstPointedKind, srcKind))
+ }
+
+ if err := mergeMaps(dst, src); err != nil {
+ return errors.WithStack(err)
+ }
+
+ case reflect.Slice:
+ if srcKind != dstPointedKind {
+ return errors.WithStack(unsupportedMergeError(dstPointedKind, srcKind))
+ }
+
+ if err := mergeSlices(dst, src); err != nil {
+ return errors.WithStack(err)
+ }
+
+ default:
+ return errors.WithStack(unsupportedMergeError(dstPointedKind, srcKind))
+ }
+ }
+
+ return nil
+}
+
+func unsupportedMergeError(dstKind reflect.Kind, defaultsKind reflect.Kind) error {
+ return errors.Wrapf(ErrUnsupportedMerge, "could not merge '%s' with defaults '%s'", dstKind, defaultsKind)
+}
+
+func mergeMaps(dst interface{}, defaults interface{}) error {
+ dstMap, ok := reflect.Indirect(reflect.ValueOf(dst)).Elem().Interface().(map[string]interface{})
+ if !ok {
+ return errors.WithStack(ErrUnexpectedFailedCast)
+ }
+
+ defaultsMap, ok := defaults.(map[string]interface{})
+ if !ok {
+ return errors.WithStack(ErrUnexpectedFailedCast)
+ }
+
+ if err := mergo.Merge(&dstMap, defaultsMap, mergo.WithOverride); err != nil {
+ return errors.WithStack(err)
+ }
+
+ return nil
+}
+
+func mergeSlices(dst interface{}, defaults interface{}) error {
+ dstSlice, ok := reflect.Indirect(reflect.ValueOf(dst)).Elem().Interface().([]interface{})
+ if !ok {
+ return errors.WithStack(ErrUnexpectedFailedCast)
+ }
+
+ defaultsSlice, ok := defaults.([]interface{})
+ if !ok {
+ return errors.WithStack(ErrUnexpectedFailedCast)
+ }
+
+ if err := mergo.Merge(&dstSlice, defaultsSlice, mergo.WithOverride); err != nil {
+ return errors.WithStack(err)
+ }
+
+ return nil
+}
diff --git a/internal/merge/merge_test.go b/internal/merge/merge_test.go
new file mode 100644
index 0000000..4d63499
--- /dev/null
+++ b/internal/merge/merge_test.go
@@ -0,0 +1,69 @@
+package merge
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/davecgh/go-spew/spew"
+)
+
+type mergeTestCase struct {
+ Name string
+ Dst interface{}
+ Dflts interface{}
+ ExpectedResult interface{}
+ ShouldFail bool
+}
+
+var mergeTestCases = []mergeTestCase{
+ {
+ Name: "simple-maps",
+ Dst: map[string]interface{}{
+ "foo": map[string]interface{}{
+ "bar": "test",
+ },
+ },
+ Dflts: map[string]interface{}{
+ "other": true,
+ "foo": map[string]interface{}{
+ "bar": true,
+ "baz": 1,
+ },
+ },
+ ExpectedResult: map[string]interface{}{
+ "foo": map[string]interface{}{
+ "bar": "test",
+ "baz": 1,
+ },
+ "other": true,
+ },
+ },
+ {
+ Name: "string-slices",
+ Dst: []string{"foo"},
+ Dflts: []string{"bar"},
+ ExpectedResult: []string{"foo"},
+ },
+}
+
+func TestMerge(t *testing.T) {
+ t.Parallel()
+
+ for _, tc := range mergeTestCases {
+ func(tc *mergeTestCase) {
+ t.Run(tc.Name, func(t *testing.T) {
+ t.Parallel()
+
+ err := Merge(&tc.Dst, tc.Dflts)
+
+ if tc.ShouldFail && err == nil {
+ t.Error("merge should have failed")
+ }
+
+ if !reflect.DeepEqual(tc.Dst, tc.ExpectedResult) {
+ t.Errorf("tc.Dst should have been the same as tc.ExpectedResult. Expected: %s, got %s", spew.Sdump(tc.ExpectedResult), spew.Sdump(tc.Dst))
+ }
+ })
+ }(&tc)
+ }
+}
diff --git a/internal/server/route.go b/internal/server/route.go
index 131743d..82e37f8 100644
--- a/internal/server/route.go
+++ b/internal/server/route.go
@@ -49,7 +49,7 @@ func (s *Server) handleFormReq(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
panic(errors.WithStack(err))
} else {
- values, err = handleForm(r.Form, s.schema, values)
+ values, err = handleForm(r.Form, s.schema, s.values)
if err != nil {
panic(errors.WithStack(err))
}
@@ -57,7 +57,7 @@ func (s *Server) handleFormReq(w http.ResponseWriter, r *http.Request) {
data.Values = values
}
- if err := s.schema.Validate(data.Values); err != nil {
+ if err := s.schema.Validate(values); err != nil {
validationErr, ok := err.(*jsonschema.ValidationError)
if !ok {
panic(errors.Wrap(err, "could not validate values"))
@@ -68,7 +68,7 @@ func (s *Server) handleFormReq(w http.ResponseWriter, r *http.Request) {
if data.Error == nil {
if s.onUpdate != nil {
- if err := s.onUpdate(data.Values); err != nil {
+ if err := s.onUpdate(values); err != nil {
panic(errors.Wrap(err, "could not update values"))
}
}
diff --git a/internal/server/template/blocks/form_input_array.html.tmpl b/internal/server/template/blocks/form_input_array.html.tmpl
index 52100a1..e8dd304 100644
--- a/internal/server/template/blocks/form_input_array.html.tmpl
+++ b/internal/server/template/blocks/form_input_array.html.tmpl
@@ -1,7 +1,7 @@
{{ define "form_input_array" }}
{{ $root := . }}
{{ $fullProperty := getFullProperty .Parent .Property }}
- {{ $values := getValue .Defaults .Values $fullProperty }}
+ {{ $values := getValue .Values $fullProperty }}
{{ range $index, $value := $values }}
diff --git a/internal/server/template/blocks/form_input_boolean.html.tmpl b/internal/server/template/blocks/form_input_boolean.html.tmpl
index b3924ef..818c6c3 100644
--- a/internal/server/template/blocks/form_input_boolean.html.tmpl
+++ b/internal/server/template/blocks/form_input_boolean.html.tmpl
@@ -1,6 +1,6 @@
{{define "form_input_boolean"}}
{{ $fullProperty := getFullProperty .Parent .Property }}
-{{ $checked := getValue .Defaults .Values $fullProperty }}
+{{ $checked := getValue .Values $fullProperty }}