mirror of https://github.com/databricks/cli.git
removed versoin from schema, this will be a separate config
This commit is contained in:
parent
4ce4b3aea1
commit
0b62f6d258
|
@ -4,6 +4,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -24,49 +25,52 @@ func setupConfig(t *testing.T, config string) string {
|
||||||
func assertFilePerm(t *testing.T, path string, perm fs.FileMode) {
|
func assertFilePerm(t *testing.T, path string, perm fs.FileMode) {
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, stat.Mode().Perm(), perm)
|
assert.Equal(t, perm, stat.Mode().Perm())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaterializeEmptyDirsAreNotGenerated(t *testing.T) {
|
func TestMaterializeEmptyDirsAreNotGenerated(t *testing.T) {
|
||||||
tmp := setupConfig(t, `
|
tmp := setupConfig(t, `
|
||||||
{
|
{
|
||||||
"a": "dir-with-file",
|
"a": "this directory is created because it contains a file",
|
||||||
"b": "foo",
|
"b": "this variable is not used anywhere",
|
||||||
"c": "dir-with-skipped-file",
|
"c": "this directory will be skipped if d=foo",
|
||||||
"d": "skipping"
|
"d": "foo"
|
||||||
}`)
|
}`)
|
||||||
err := Materialize("./testdata/skip_dir", tmp, filepath.Join(tmp, "config.json"))
|
err := Materialize("./testdata/skip_dir", tmp, filepath.Join(tmp, "config.json"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.DirExists(t, filepath.Join(tmp, "dir-with-file"))
|
assert.DirExists(t, filepath.Join(tmp, "this directory is created because it contains a file"))
|
||||||
assert.FileExists(t, filepath.Join(tmp, "dir-with-file/.gitkeep"))
|
assert.FileExists(t, filepath.Join(tmp, "this directory is created because it contains a file/.gitkeep"))
|
||||||
assert.NoDirExists(t, filepath.Join(tmp, "empty-dir"))
|
assert.NoDirExists(t, filepath.Join(tmp, "this directory will be skipped if d=foo"))
|
||||||
assert.NoDirExists(t, filepath.Join(tmp, "dir-with-skipped-file"))
|
|
||||||
|
|
||||||
tmp2 := setupConfig(t, `
|
tmp2 := setupConfig(t, `
|
||||||
{
|
{
|
||||||
"a": "dir-with-file",
|
"a": "this directory is created because it contains a file",
|
||||||
"b": "foo",
|
"b": "this variable is not used anywhere",
|
||||||
"c": "dir-not-skipped-this-time",
|
"c": "this directory will be skipped if d=foo",
|
||||||
"d": "not-skipping"
|
"d": "bar"
|
||||||
}`)
|
}`)
|
||||||
err = Materialize("./testdata/skip_dir", tmp2, filepath.Join(tmp2, "config.json"))
|
err = Materialize("./testdata/skip_dir", tmp2, filepath.Join(tmp2, "config.json"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.DirExists(t, filepath.Join(tmp2, "dir-with-file"))
|
assert.DirExists(t, filepath.Join(tmp2, "this directory is created because it contains a file"))
|
||||||
assert.FileExists(t, filepath.Join(tmp2, "dir-with-file/.gitkeep"))
|
assert.FileExists(t, filepath.Join(tmp2, "this directory is created because it contains a file/.gitkeep"))
|
||||||
assert.DirExists(t, filepath.Join(tmp2, "dir-not-skipped-this-time"))
|
assert.DirExists(t, filepath.Join(tmp2, "this directory will be skipped if d=foo"))
|
||||||
assert.FileExists(t, filepath.Join(tmp2, "dir-not-skipped-this-time/foo"))
|
assert.FileExists(t, filepath.Join(tmp2, "this directory will be skipped if d=foo/abc"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaterializedTemplatesHaveIdenticalFilePermissionsAsTemplate(t *testing.T) {
|
func TestMaterializeFilePermissionsAreCopiedForUnix(t *testing.T) {
|
||||||
// create template
|
if runtime.GOOS == "windows" {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
tmp := t.TempDir()
|
tmp := t.TempDir()
|
||||||
|
|
||||||
|
// create template schema in temp directory
|
||||||
err := os.Mkdir(filepath.Join(tmp, "my_tmpl"), 0777)
|
err := os.Mkdir(filepath.Join(tmp, "my_tmpl"), 0777)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = os.WriteFile(filepath.Join(tmp, "my_tmpl", "schema.json"), []byte(`
|
err = os.WriteFile(filepath.Join(tmp, "my_tmpl", "schema.json"), []byte(`
|
||||||
{
|
{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"a": {
|
"a": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -122,3 +126,61 @@ func TestMaterializedTemplatesHaveIdenticalFilePermissionsAsTemplate(t *testing.
|
||||||
assertFilePerm(t, filepath.Join(instanceRoot, "foo"), 0500)
|
assertFilePerm(t, filepath.Join(instanceRoot, "foo"), 0500)
|
||||||
assertFilePerm(t, filepath.Join(instanceRoot, "bar"), 0755)
|
assertFilePerm(t, filepath.Join(instanceRoot, "bar"), 0755)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMaterializeFilePermissionsAreCopiedForWindows(t *testing.T) {
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := t.TempDir()
|
||||||
|
|
||||||
|
// create template in temp directory
|
||||||
|
err := os.Mkdir(filepath.Join(tmp, "my_tmpl"), 0777)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.WriteFile(filepath.Join(tmp, "my_tmpl", "schema.json"), []byte(`
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// A normal file with the executable bit not flipped
|
||||||
|
err = os.Mkdir(filepath.Join(tmp, "my_tmpl", "template"), 0777)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.WriteFile(filepath.Join(tmp, "my_tmpl", "template", "{{.a}}"), []byte("abc"), 0666)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// A read only file
|
||||||
|
err = os.WriteFile(filepath.Join(tmp, "my_tmpl", "template", "{{.b}}"), []byte("def"), 0444)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create config.json file
|
||||||
|
err = os.Mkdir(filepath.Join(tmp, "config"), 0777)
|
||||||
|
require.NoError(t, err)
|
||||||
|
configPath := filepath.Join(tmp, "config", "config.json")
|
||||||
|
err = os.WriteFile(configPath, []byte(`
|
||||||
|
{
|
||||||
|
"a": "Amsterdam",
|
||||||
|
"b": "Hague"
|
||||||
|
}`), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create directory to initialize the template in
|
||||||
|
instanceRoot := filepath.Join(tmp, "instance")
|
||||||
|
err = os.Mkdir(instanceRoot, 0777)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// materialize the template
|
||||||
|
err = Materialize(filepath.Join(tmp, "my_tmpl"), instanceRoot, configPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// assert template files have the correct permission bits set
|
||||||
|
assertFilePerm(t, filepath.Join(instanceRoot, "Amsterdam"), 0600)
|
||||||
|
assertFilePerm(t, filepath.Join(instanceRoot, "Hague"), 0400)
|
||||||
|
}
|
||||||
|
|
|
@ -9,27 +9,25 @@ import (
|
||||||
|
|
||||||
const LatestSchemaVersion = 0
|
const LatestSchemaVersion = 0
|
||||||
|
|
||||||
|
// This is a JSON Schema compliant struct that we use to do validation checks on
|
||||||
|
// the provided configuration
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
// A version for the template schema
|
|
||||||
Version int `json:"version"`
|
|
||||||
|
|
||||||
// A list of properties that can be used in the config
|
// A list of properties that can be used in the config
|
||||||
Properties map[string]FieldInfo `json:"properties"`
|
Properties map[string]Property `json:"properties"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FieldType string
|
type PropertyType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FieldTypeString = FieldType("string")
|
PropertyTypeString = PropertyType("string")
|
||||||
FieldTypeInt = FieldType("integer")
|
PropertyTypeInt = PropertyType("integer")
|
||||||
FieldTypeFloat = FieldType("float")
|
PropertyTypeNumber = PropertyType("number")
|
||||||
FieldTypeBoolean = FieldType("boolean")
|
PropertyTypeBoolean = PropertyType("boolean")
|
||||||
)
|
)
|
||||||
|
|
||||||
type FieldInfo struct {
|
type Property struct {
|
||||||
Type FieldType `json:"type"`
|
Type PropertyType `json:"type"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Validation string `json:"validation"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to check whether a float value represents an integer
|
// function to check whether a float value represents an integer
|
||||||
|
@ -38,7 +36,7 @@ func isIntegerValue(v float64) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast value to integer for config values that are floats but are supposed to be
|
// cast value to integer for config values that are floats but are supposed to be
|
||||||
// integeres according to the schema
|
// integers according to the schema
|
||||||
//
|
//
|
||||||
// Needed because the default json unmarshaller for maps converts all numbers to floats
|
// Needed because the default json unmarshaller for maps converts all numbers to floats
|
||||||
func castFloatToInt(config map[string]any, schema *Schema) error {
|
func castFloatToInt(config map[string]any, schema *Schema) error {
|
||||||
|
@ -50,7 +48,7 @@ func castFloatToInt(config map[string]any, schema *Schema) error {
|
||||||
|
|
||||||
// skip non integer fields
|
// skip non integer fields
|
||||||
fieldInfo := schema.Properties[k]
|
fieldInfo := schema.Properties[k]
|
||||||
if fieldInfo.Type != FieldTypeInt {
|
if fieldInfo.Type != PropertyTypeInt {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ func castFloatToInt(config map[string]any, schema *Schema) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateType(v any, fieldType FieldType) error {
|
func validateType(v any, fieldType PropertyType) error {
|
||||||
validateFunc, ok := validators[fieldType]
|
validateFunc, ok := validators[fieldType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -21,13 +21,12 @@ func TestTemplateSchematIsInterger(t *testing.T) {
|
||||||
func TestTemplateSchemaCastFloatToInt(t *testing.T) {
|
func TestTemplateSchemaCastFloatToInt(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"int_val": {
|
"int_val": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"float_val": {
|
"float_val": {
|
||||||
"type": "float"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"bool_val": {
|
"bool_val": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -73,7 +72,6 @@ func TestTemplateSchemaCastFloatToInt(t *testing.T) {
|
||||||
func TestTemplateSchemaCastFloatToIntFailsForUnknownTypes(t *testing.T) {
|
func TestTemplateSchemaCastFloatToIntFailsForUnknownTypes(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"foo": {
|
"foo": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
@ -99,7 +97,6 @@ func TestTemplateSchemaCastFloatToIntFailsForUnknownTypes(t *testing.T) {
|
||||||
func TestTemplateSchemaCastFloatToIntFailsWhenWithNonIntValues(t *testing.T) {
|
func TestTemplateSchemaCastFloatToIntFailsWhenWithNonIntValues(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"foo": {
|
"foo": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
@ -124,70 +121,69 @@ func TestTemplateSchemaCastFloatToIntFailsWhenWithNonIntValues(t *testing.T) {
|
||||||
|
|
||||||
func TestTemplateSchemaValidateType(t *testing.T) {
|
func TestTemplateSchemaValidateType(t *testing.T) {
|
||||||
// assert validation passing
|
// assert validation passing
|
||||||
err := validateType(int(0), FieldTypeInt)
|
err := validateType(int(0), PropertyTypeInt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType(int32(1), FieldTypeInt)
|
err = validateType(int32(1), PropertyTypeInt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType(int64(1), FieldTypeInt)
|
err = validateType(int64(1), PropertyTypeInt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType(float32(1.1), FieldTypeFloat)
|
err = validateType(float32(1.1), PropertyTypeNumber)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType(float64(1.2), FieldTypeFloat)
|
err = validateType(float64(1.2), PropertyTypeNumber)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType(false, FieldTypeBoolean)
|
err = validateType(false, PropertyTypeBoolean)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = validateType("abc", FieldTypeString)
|
err = validateType("abc", PropertyTypeString)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// assert validation failing for integers
|
// assert validation failing for integers
|
||||||
err = validateType(float64(1.2), FieldTypeInt)
|
err = validateType(float64(1.2), PropertyTypeInt)
|
||||||
assert.ErrorContains(t, err, "expected type integer, but value is 1.2")
|
assert.ErrorContains(t, err, "expected type integer, but value is 1.2")
|
||||||
err = validateType(true, FieldTypeInt)
|
err = validateType(true, PropertyTypeInt)
|
||||||
assert.ErrorContains(t, err, "expected type integer, but value is true")
|
assert.ErrorContains(t, err, "expected type integer, but value is true")
|
||||||
err = validateType("abc", FieldTypeInt)
|
err = validateType("abc", PropertyTypeInt)
|
||||||
assert.ErrorContains(t, err, "expected type integer, but value is \"abc\"")
|
assert.ErrorContains(t, err, "expected type integer, but value is \"abc\"")
|
||||||
|
|
||||||
// assert validation failing for floats
|
// assert validation failing for floats
|
||||||
err = validateType(int(1), FieldTypeFloat)
|
err = validateType(int(1), PropertyTypeNumber)
|
||||||
assert.ErrorContains(t, err, "expected type float, but value is 1")
|
assert.ErrorContains(t, err, "expected type float, but value is 1")
|
||||||
err = validateType(true, FieldTypeFloat)
|
err = validateType(true, PropertyTypeNumber)
|
||||||
assert.ErrorContains(t, err, "expected type float, but value is true")
|
assert.ErrorContains(t, err, "expected type float, but value is true")
|
||||||
err = validateType("abc", FieldTypeFloat)
|
err = validateType("abc", PropertyTypeNumber)
|
||||||
assert.ErrorContains(t, err, "expected type float, but value is \"abc\"")
|
assert.ErrorContains(t, err, "expected type float, but value is \"abc\"")
|
||||||
|
|
||||||
// assert validation failing for boolean
|
// assert validation failing for boolean
|
||||||
err = validateType(int(1), FieldTypeBoolean)
|
err = validateType(int(1), PropertyTypeBoolean)
|
||||||
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
|
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
|
||||||
err = validateType(float64(1), FieldTypeBoolean)
|
err = validateType(float64(1), PropertyTypeBoolean)
|
||||||
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
|
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
|
||||||
err = validateType("abc", FieldTypeBoolean)
|
err = validateType("abc", PropertyTypeBoolean)
|
||||||
assert.ErrorContains(t, err, "expected type boolean, but value is \"abc\"")
|
assert.ErrorContains(t, err, "expected type boolean, but value is \"abc\"")
|
||||||
|
|
||||||
// assert validation failing for string
|
// assert validation failing for string
|
||||||
err = validateType(int(1), FieldTypeString)
|
err = validateType(int(1), PropertyTypeString)
|
||||||
assert.ErrorContains(t, err, "expected type string, but value is 1")
|
assert.ErrorContains(t, err, "expected type string, but value is 1")
|
||||||
err = validateType(float64(1), FieldTypeString)
|
err = validateType(float64(1), PropertyTypeString)
|
||||||
assert.ErrorContains(t, err, "expected type string, but value is 1")
|
assert.ErrorContains(t, err, "expected type string, but value is 1")
|
||||||
err = validateType(false, FieldTypeString)
|
err = validateType(false, PropertyTypeString)
|
||||||
assert.ErrorContains(t, err, "expected type string, but value is false")
|
assert.ErrorContains(t, err, "expected type string, but value is false")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTemplateSchemaValidateConfig(t *testing.T) {
|
func TestTemplateSchemaValidateConfig(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"int_val": {
|
"int_val": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"float_val": {
|
"float_val": {
|
||||||
"type": "float"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"bool_val": {
|
"bool_val": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -216,13 +212,12 @@ func TestTemplateSchemaValidateConfig(t *testing.T) {
|
||||||
func TestTemplateSchemaValidateConfigFailsForUnknownField(t *testing.T) {
|
func TestTemplateSchemaValidateConfigFailsForUnknownField(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"int_val": {
|
"int_val": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"float_val": {
|
"float_val": {
|
||||||
"type": "float"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"bool_val": {
|
"bool_val": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -251,13 +246,12 @@ func TestTemplateSchemaValidateConfigFailsForUnknownField(t *testing.T) {
|
||||||
func TestTemplateSchemaValidateConfigFailsForWhenIncorrectTypes(t *testing.T) {
|
func TestTemplateSchemaValidateConfigFailsForWhenIncorrectTypes(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"int_val": {
|
"int_val": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"float_val": {
|
"float_val": {
|
||||||
"type": "float"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"bool_val": {
|
"bool_val": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -286,7 +280,6 @@ func TestTemplateSchemaValidateConfigFailsForWhenIncorrectTypes(t *testing.T) {
|
||||||
func TestTemplateSchemaValidateConfigFailsForWhenMissingInputParams(t *testing.T) {
|
func TestTemplateSchemaValidateConfigFailsForWhenMissingInputParams(t *testing.T) {
|
||||||
// define schema for config
|
// define schema for config
|
||||||
schemaJson := `{
|
schemaJson := `{
|
||||||
"version": 0,
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"int_val": {
|
"int_val": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{{if eq .d "foo"}}
|
||||||
|
{{skipThisFile}}
|
||||||
|
{{end}}
|
||||||
|
Hello, World
|
|
@ -1,4 +0,0 @@
|
||||||
{{if eq .d "skipping"}}
|
|
||||||
{{skipThisFile}}
|
|
||||||
{{end}}
|
|
||||||
Hello!
|
|
|
@ -39,9 +39,9 @@ func validateInteger(v any) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var validators map[FieldType]Validator = map[FieldType]Validator{
|
var validators map[PropertyType]Validator = map[PropertyType]Validator{
|
||||||
FieldTypeString: validateString,
|
PropertyTypeString: validateString,
|
||||||
FieldTypeBoolean: validateBoolean,
|
PropertyTypeBoolean: validateBoolean,
|
||||||
FieldTypeInt: validateInteger,
|
PropertyTypeInt: validateInteger,
|
||||||
FieldTypeFloat: validateFloat,
|
PropertyTypeNumber: validateFloat,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue