updated automigrate templates, added js bindings tests and updated models IsNew behavior
This commit is contained in:
@@ -65,7 +65,7 @@ func RegisterMigrations(app core.App, options *MigrationsOptions) error {
|
||||
registry := new(require.Registry) // this can be shared by multiple runtimes
|
||||
|
||||
for file, content := range files {
|
||||
vm := NewBaseVM(l.app)
|
||||
vm := NewBaseVM()
|
||||
registry.Enable(vm)
|
||||
console.Enable(vm)
|
||||
|
||||
|
||||
+48
-29
@@ -9,24 +9,22 @@ import (
|
||||
"github.com/dop251/goja"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/apis"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
func NewBaseVM(app core.App) *goja.Runtime {
|
||||
func NewBaseVM() *goja.Runtime {
|
||||
vm := goja.New()
|
||||
vm.SetFieldNameMapper(fieldMapper{})
|
||||
vm.Set("$app", app)
|
||||
vm.SetFieldNameMapper(FieldMapper{})
|
||||
|
||||
baseBind(vm)
|
||||
dbxBind(vm)
|
||||
baseBinds(vm)
|
||||
dbxBinds(vm)
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
func baseBind(vm *goja.Runtime) {
|
||||
func baseBinds(vm *goja.Runtime) {
|
||||
vm.Set("unmarshal", func(src map[string]any, dest any) (any, error) {
|
||||
raw, err := json.Marshal(src)
|
||||
if err != nil {
|
||||
@@ -40,39 +38,46 @@ func baseBind(vm *goja.Runtime) {
|
||||
return dest, nil
|
||||
})
|
||||
|
||||
vm.Set("Collection", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &models.Collection{}
|
||||
vm.Set("Record", func(call goja.ConstructorCall) *goja.Object {
|
||||
var instance *models.Record
|
||||
|
||||
collection, ok := call.Argument(0).Export().(*models.Collection)
|
||||
if ok {
|
||||
instance = models.NewRecord(collection)
|
||||
data, ok := call.Argument(1).Export().(map[string]any)
|
||||
if ok {
|
||||
if raw, err := json.Marshal(data); err == nil {
|
||||
json.Unmarshal(raw, instance)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
instance = &models.Record{}
|
||||
}
|
||||
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
|
||||
return instanceValue
|
||||
})
|
||||
|
||||
vm.Set("Record", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &models.Record{}
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
return instanceValue
|
||||
vm.Set("Collection", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &models.Collection{}
|
||||
return defaultConstructor(vm, call, instance)
|
||||
})
|
||||
|
||||
vm.Set("Admin", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &models.Admin{}
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
return instanceValue
|
||||
return defaultConstructor(vm, call, instance)
|
||||
})
|
||||
|
||||
vm.Set("Schema", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &schema.Schema{}
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
return instanceValue
|
||||
return defaultConstructor(vm, call, instance)
|
||||
})
|
||||
|
||||
vm.Set("SchemaField", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := &schema.SchemaField{}
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
return instanceValue
|
||||
return defaultConstructor(vm, call, instance)
|
||||
})
|
||||
|
||||
vm.Set("Dao", func(call goja.ConstructorCall) *goja.Object {
|
||||
@@ -84,11 +89,25 @@ func baseBind(vm *goja.Runtime) {
|
||||
instance := daos.New(db)
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
|
||||
return instanceValue
|
||||
})
|
||||
}
|
||||
|
||||
func dbxBind(vm *goja.Runtime) {
|
||||
func defaultConstructor(vm *goja.Runtime, call goja.ConstructorCall, instance any) *goja.Object {
|
||||
if data := call.Argument(0).Export(); data != nil {
|
||||
if raw, err := json.Marshal(data); err == nil {
|
||||
json.Unmarshal(raw, instance)
|
||||
}
|
||||
}
|
||||
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
instanceValue.SetPrototype(call.This.Prototype())
|
||||
|
||||
return instanceValue
|
||||
}
|
||||
|
||||
func dbxBinds(vm *goja.Runtime) {
|
||||
obj := vm.NewObject()
|
||||
vm.Set("$dbx", obj)
|
||||
|
||||
@@ -141,27 +160,27 @@ func apisBind(vm *goja.Runtime) {
|
||||
obj.Set("enrichRecords", apis.EnrichRecords)
|
||||
}
|
||||
|
||||
// fieldMapper provides custom mapping between Go and JavaScript property names.
|
||||
// FieldMapper provides custom mapping between Go and JavaScript property names.
|
||||
//
|
||||
// It is similar to the builtin "uncapFieldNameMapper" but also converts
|
||||
// all uppercase identifiers to their lowercase equivalent (eg. "GET" -> "get").
|
||||
type fieldMapper struct {
|
||||
type FieldMapper struct {
|
||||
}
|
||||
|
||||
// FieldName implements the [FieldNameMapper.FieldName] interface method.
|
||||
func (u fieldMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
|
||||
func (u FieldMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
|
||||
return convertGoToJSName(f.Name)
|
||||
}
|
||||
|
||||
// MethodName implements the [FieldNameMapper.MethodName] interface method.
|
||||
func (u fieldMapper) MethodName(_ reflect.Type, m reflect.Method) string {
|
||||
func (u FieldMapper) MethodName(_ reflect.Type, m reflect.Method) string {
|
||||
return convertGoToJSName(m.Name)
|
||||
}
|
||||
|
||||
func convertGoToJSName(name string) string {
|
||||
allUppercase := true
|
||||
for _, c := range name {
|
||||
if !unicode.IsUpper(c) {
|
||||
if c != '_' && !unicode.IsUpper(c) {
|
||||
allUppercase = false
|
||||
break
|
||||
}
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
package jsvm_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
"github.com/pocketbase/pocketbase/plugins/jsvm"
|
||||
"github.com/pocketbase/pocketbase/tests"
|
||||
)
|
||||
|
||||
func TestBaseVMUnmarshal(t *testing.T) {
|
||||
vm := jsvm.NewBaseVM()
|
||||
|
||||
v, err := vm.RunString(`unmarshal({ name: "test" }, new Collection())`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, ok := v.Export().(*models.Collection)
|
||||
if !ok {
|
||||
t.Fatalf("Expected models.Collection, got %v", m)
|
||||
}
|
||||
|
||||
if m.Name != "test" {
|
||||
t.Fatalf("Expected collection with name %q, got %q", "test", m.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseVMRecordBind(t *testing.T) {
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
collection, err := app.Dao().FindCollectionByNameOrId("users")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vm := jsvm.NewBaseVM()
|
||||
vm.Set("collection", collection)
|
||||
|
||||
// without record data
|
||||
// ---
|
||||
v1, err := vm.RunString(`new Record(collection)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m1, ok := v1.Export().(*models.Record)
|
||||
if !ok {
|
||||
t.Fatalf("Expected m1 to be models.Record, got \n%v", m1)
|
||||
}
|
||||
|
||||
// with record data
|
||||
// ---
|
||||
v2, err := vm.RunString(`new Record(collection, { email: "test@example.com" })`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m2, ok := v2.Export().(*models.Record)
|
||||
if !ok {
|
||||
t.Fatalf("Expected m2 to be models.Record, got \n%v", m2)
|
||||
}
|
||||
|
||||
if m2.Collection().Name != "users" {
|
||||
t.Fatalf("Expected record with collection %q, got \n%v", "users", m2.Collection())
|
||||
}
|
||||
|
||||
if m2.Email() != "test@example.com" {
|
||||
t.Fatalf("Expected record with email field set to %q, got \n%v", "test@example.com", m2)
|
||||
}
|
||||
}
|
||||
|
||||
// @todo enable after https://github.com/dop251/goja/issues/426
|
||||
// func TestBaseVMRecordGetAndSetBind(t *testing.T) {
|
||||
// app, _ := tests.NewTestApp()
|
||||
// defer app.Cleanup()
|
||||
|
||||
// collection, err := app.Dao().FindCollectionByNameOrId("users")
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// vm := jsvm.NewBaseVM()
|
||||
// vm.Set("collection", collection)
|
||||
// vm.Set("getRecord", func() *models.Record {
|
||||
// return models.NewRecord(collection)
|
||||
// })
|
||||
|
||||
// _, runErr := vm.RunString(`
|
||||
// const jsRecord = new Record(collection);
|
||||
// jsRecord.email = "test@example.com"; // test js record setter
|
||||
// const email = jsRecord.email; // test js record getter
|
||||
|
||||
// const goRecord = getRecord()
|
||||
// goRecord.name = "test" // test go record setter
|
||||
// const name = goRecord.name; // test go record getter
|
||||
// `)
|
||||
// if runErr != nil {
|
||||
// t.Fatal(runErr)
|
||||
// }
|
||||
|
||||
// expectedEmail := "test@example.com"
|
||||
// expectedName := "test"
|
||||
|
||||
// jsRecord, ok := vm.Get("jsRecord").Export().(*models.Record)
|
||||
// if !ok {
|
||||
// t.Fatalf("Failed to export jsRecord")
|
||||
// }
|
||||
// if v := jsRecord.Email(); v != expectedEmail {
|
||||
// t.Fatalf("Expected the js created record to have email %q, got %q", expectedEmail, v)
|
||||
// }
|
||||
|
||||
// email := vm.Get("email").Export().(string)
|
||||
// if email != expectedEmail {
|
||||
// t.Fatalf("Expected exported email %q, got %q", expectedEmail, email)
|
||||
// }
|
||||
|
||||
// goRecord, ok := vm.Get("goRecord").Export().(*models.Record)
|
||||
// if !ok {
|
||||
// t.Fatalf("Failed to export goRecord")
|
||||
// }
|
||||
// if v := goRecord.GetString("name"); v != expectedName {
|
||||
// t.Fatalf("Expected the go created record to have name %q, got %q", expectedName, v)
|
||||
// }
|
||||
|
||||
// name := vm.Get("name").Export().(string)
|
||||
// if name != expectedName {
|
||||
// t.Fatalf("Expected exported name %q, got %q", expectedName, name)
|
||||
// }
|
||||
|
||||
// // ensure that the two record instances are not mixed
|
||||
// if v := goRecord.Email(); v != "" {
|
||||
// t.Fatalf("Expected the go created record to not have an email, got %q", v)
|
||||
// }
|
||||
// if v := jsRecord.GetString("name"); v != "" {
|
||||
// t.Fatalf("Expected the js created record to not have a name, got %q", v)
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestBaseVMCollectionBind(t *testing.T) {
|
||||
vm := jsvm.NewBaseVM()
|
||||
|
||||
v, err := vm.RunString(`new Collection({ name: "test", schema: [{name: "title", "type": "text"}] })`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, ok := v.Export().(*models.Collection)
|
||||
if !ok {
|
||||
t.Fatalf("Expected models.Collection, got %v", m)
|
||||
}
|
||||
|
||||
if m.Name != "test" {
|
||||
t.Fatalf("Expected collection with name %q, got %q", "test", m.Name)
|
||||
}
|
||||
|
||||
if f := m.Schema.GetFieldByName("title"); f == nil {
|
||||
t.Fatalf("Expected schema to be set, got %v", m.Schema)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseVMAdminBind(t *testing.T) {
|
||||
vm := jsvm.NewBaseVM()
|
||||
|
||||
v, err := vm.RunString(`new Admin({ email: "test@example.com" })`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, ok := v.Export().(*models.Admin)
|
||||
if !ok {
|
||||
t.Fatalf("Expected models.Admin, got %v", m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseVMSchemaBind(t *testing.T) {
|
||||
vm := jsvm.NewBaseVM()
|
||||
|
||||
v, err := vm.RunString(`new Schema([{name: "title", "type": "text"}])`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, ok := v.Export().(*schema.Schema)
|
||||
if !ok {
|
||||
t.Fatalf("Expected schema.Schema, got %v", m)
|
||||
}
|
||||
|
||||
if f := m.GetFieldByName("title"); f == nil {
|
||||
t.Fatalf("Expected schema fields to be loaded, got %v", m.Fields())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseVMSchemaFieldBind(t *testing.T) {
|
||||
vm := jsvm.NewBaseVM()
|
||||
|
||||
v, err := vm.RunString(`new SchemaField({name: "title", "type": "text"})`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, ok := v.Export().(*schema.SchemaField)
|
||||
if !ok {
|
||||
t.Fatalf("Expected schema.SchemaField, got %v", f)
|
||||
}
|
||||
|
||||
if f.Name != "title" {
|
||||
t.Fatalf("Expected field %q, got %v", "title", f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseVMDaoBind(t *testing.T) {
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
vm := jsvm.NewBaseVM()
|
||||
vm.Set("db", app.DB())
|
||||
|
||||
v, err := vm.RunString(`new Dao(db)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
d, ok := v.Export().(*daos.Dao)
|
||||
if !ok {
|
||||
t.Fatalf("Expected daos.Dao, got %v", d)
|
||||
}
|
||||
|
||||
if d.DB() != app.DB() {
|
||||
t.Fatalf("The db instances doesn't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldMapper(t *testing.T) {
|
||||
mapper := jsvm.FieldMapper{}
|
||||
|
||||
scenarios := []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"", ""},
|
||||
{"test", "test"},
|
||||
{"Test", "test"},
|
||||
{"miXeD", "miXeD"},
|
||||
{"MiXeD", "miXeD"},
|
||||
{"ResolveRequestAsJSON", "resolveRequestAsJSON"},
|
||||
{"Variable_with_underscore", "variable_with_underscore"},
|
||||
{"ALLCAPS", "allcaps"},
|
||||
{"NOTALLCAPs", "nOTALLCAPs"},
|
||||
{"ALL_CAPS_WITH_UNDERSCORE", "all_caps_with_underscore"},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
field := reflect.StructField{Name: s.name}
|
||||
if v := mapper.FieldName(nil, field); v != s.expected {
|
||||
t.Fatalf("[%d] Expected FieldName %q, got %q", i, s.expected, v)
|
||||
}
|
||||
|
||||
method := reflect.Method{Name: s.name}
|
||||
if v := mapper.MethodName(nil, method); v != s.expected {
|
||||
t.Fatalf("[%d] Expected MethodName %q, got %q", i, s.expected, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,3 +136,19 @@ func (p *plugin) getCachedCollections() (map[string]*models.Collection, error) {
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *plugin) hasCustomMigrations() bool {
|
||||
files, err := os.ReadDir(p.options.Dir)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -82,6 +82,15 @@ func Register(app core.App, rootCmd *cobra.Command, options *Options) error {
|
||||
// when migrations are applied on server start
|
||||
p.app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||
p.refreshCachedCollections()
|
||||
|
||||
cachedCollections, _ := p.getCachedCollections()
|
||||
// create a full initial snapshot, if there are no custom
|
||||
// migrations but there is already at least 1 collection created,
|
||||
// to ensure that the automigrate will work with up-to-date collections data
|
||||
if !p.hasCustomMigrations() && len(cachedCollections) > 1 {
|
||||
p.migrateCollectionsHandler(nil, false)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -114,11 +123,11 @@ func (p *plugin) createCommand() *cobra.Command {
|
||||
|
||||
switch cmd {
|
||||
case "create":
|
||||
if err := p.migrateCreateHandler("", args[1:]); err != nil {
|
||||
if err := p.migrateCreateHandler("", args[1:], true); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case "collections":
|
||||
if err := p.migrateCollectionsHandler(args[1:]); err != nil {
|
||||
if err := p.migrateCollectionsHandler(args[1:], true); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
default:
|
||||
@@ -137,7 +146,7 @@ func (p *plugin) createCommand() *cobra.Command {
|
||||
return command
|
||||
}
|
||||
|
||||
func (p *plugin) migrateCreateHandler(template string, args []string) error {
|
||||
func (p *plugin) migrateCreateHandler(template string, args []string, interactive bool) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("Missing migration file name")
|
||||
}
|
||||
@@ -150,14 +159,16 @@ func (p *plugin) migrateCreateHandler(template string, args []string) error {
|
||||
fmt.Sprintf("%d_%s.%s", time.Now().Unix(), inflector.Snakecase(name), p.options.TemplateLang),
|
||||
)
|
||||
|
||||
confirm := false
|
||||
prompt := &survey.Confirm{
|
||||
Message: fmt.Sprintf("Do you really want to create migration %q?", resultFilePath),
|
||||
}
|
||||
survey.AskOne(prompt, &confirm)
|
||||
if !confirm {
|
||||
fmt.Println("The command has been cancelled")
|
||||
return nil
|
||||
if interactive {
|
||||
confirm := false
|
||||
prompt := &survey.Confirm{
|
||||
Message: fmt.Sprintf("Do you really want to create migration %q?", resultFilePath),
|
||||
}
|
||||
survey.AskOne(prompt, &confirm)
|
||||
if !confirm {
|
||||
fmt.Println("The command has been cancelled")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// get default create template
|
||||
@@ -183,11 +194,14 @@ func (p *plugin) migrateCreateHandler(template string, args []string) error {
|
||||
return fmt.Errorf("Failed to save migration file %q: %v\n", resultFilePath, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully created file %q\n", resultFilePath)
|
||||
if interactive {
|
||||
fmt.Printf("Successfully created file %q\n", resultFilePath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) migrateCollectionsHandler(args []string) error {
|
||||
func (p *plugin) migrateCollectionsHandler(args []string, interactive bool) error {
|
||||
createArgs := []string{"collections_snapshot"}
|
||||
createArgs = append(createArgs, args...)
|
||||
|
||||
@@ -207,5 +221,5 @@ func (p *plugin) migrateCollectionsHandler(args []string) error {
|
||||
return fmt.Errorf("Failed to resolve template: %v", templateErr)
|
||||
}
|
||||
|
||||
return p.migrateCreateHandler(template, createArgs)
|
||||
return p.migrateCreateHandler(template, createArgs, interactive)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestAutomigrateCollectionCreate(t *testing.T) {
|
||||
migratecmd.TemplateLangJS,
|
||||
`
|
||||
migrate((db) => {
|
||||
const collection = unmarshal({
|
||||
const collection = new Collection({
|
||||
"id": "new_id",
|
||||
"created": "2022-01-01 00:00:00.000Z",
|
||||
"updated": "2022-01-01 00:00:00.000Z",
|
||||
@@ -46,7 +46,7 @@ migrate((db) => {
|
||||
"onlyEmailDomains": null,
|
||||
"requireEmail": false
|
||||
}
|
||||
}, new Collection());
|
||||
});
|
||||
|
||||
return Dao(db).saveCollection(collection);
|
||||
}, (db) => {
|
||||
@@ -193,7 +193,7 @@ migrate((db) => {
|
||||
|
||||
return dao.deleteCollection(collection);
|
||||
}, (db) => {
|
||||
const collection = unmarshal({
|
||||
const collection = new Collection({
|
||||
"id": "test123",
|
||||
"created": "2022-01-01 00:00:00.000Z",
|
||||
"updated": "2022-01-01 00:00:00.000Z",
|
||||
@@ -216,7 +216,7 @@ migrate((db) => {
|
||||
"onlyEmailDomains": null,
|
||||
"requireEmail": false
|
||||
}
|
||||
}, new Collection());
|
||||
});
|
||||
|
||||
return Dao(db).saveCollection(collection);
|
||||
})
|
||||
@@ -372,7 +372,7 @@ migrate((db) => {
|
||||
collection.schema.removeField("f3_id")
|
||||
|
||||
// add
|
||||
collection.schema.addField(unmarshal({
|
||||
collection.schema.addField(new SchemaField({
|
||||
"system": false,
|
||||
"id": "f4_id",
|
||||
"name": "f4_name",
|
||||
@@ -384,10 +384,10 @@ migrate((db) => {
|
||||
"max": null,
|
||||
"pattern": "` + "`" + `test backtick` + "`" + `123"
|
||||
}
|
||||
}, new SchemaField()))
|
||||
}))
|
||||
|
||||
// update
|
||||
collection.schema.addField(unmarshal({
|
||||
collection.schema.addField(new SchemaField({
|
||||
"system": false,
|
||||
"id": "f2_id",
|
||||
"name": "f2_name_new",
|
||||
@@ -398,7 +398,7 @@ migrate((db) => {
|
||||
"min": 10,
|
||||
"max": null
|
||||
}
|
||||
}, new SchemaField()))
|
||||
}))
|
||||
|
||||
return dao.saveCollection(collection)
|
||||
}, (db) => {
|
||||
@@ -421,7 +421,7 @@ migrate((db) => {
|
||||
}
|
||||
|
||||
// add
|
||||
collection.schema.addField(unmarshal({
|
||||
collection.schema.addField(new SchemaField({
|
||||
"system": false,
|
||||
"id": "f3_id",
|
||||
"name": "f3_name",
|
||||
@@ -429,13 +429,13 @@ migrate((db) => {
|
||||
"required": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}, new SchemaField()))
|
||||
}))
|
||||
|
||||
// remove
|
||||
collection.schema.removeField("f4_id")
|
||||
|
||||
// update
|
||||
collection.schema.addField(unmarshal({
|
||||
collection.schema.addField(new SchemaField({
|
||||
"system": false,
|
||||
"id": "f2_id",
|
||||
"name": "f2_name",
|
||||
@@ -446,7 +446,7 @@ migrate((db) => {
|
||||
"min": 10,
|
||||
"max": null
|
||||
}
|
||||
}, new SchemaField()))
|
||||
}))
|
||||
|
||||
return dao.saveCollection(collection)
|
||||
})
|
||||
|
||||
@@ -43,7 +43,7 @@ func (p *plugin) jsSnapshotTemplate(collections []*models.Collection) (string, e
|
||||
const template = `migrate((db) => {
|
||||
const snapshot = %s;
|
||||
|
||||
const collections = snapshot.map((item) => unmarshal(item, new Collection()));
|
||||
const collections = snapshot.map((item) => new Collection(item));
|
||||
|
||||
return Dao(db).importCollections(collections, true, null);
|
||||
}, (db) => {
|
||||
@@ -61,7 +61,7 @@ func (p *plugin) jsCreateTemplate(collection *models.Collection) (string, error)
|
||||
}
|
||||
|
||||
const template = `migrate((db) => {
|
||||
const collection = unmarshal(%s, new Collection());
|
||||
const collection = new Collection(%s);
|
||||
|
||||
return Dao(db).saveCollection(collection);
|
||||
}, (db) => {
|
||||
@@ -87,7 +87,7 @@ func (p *plugin) jsDeleteTemplate(collection *models.Collection) (string, error)
|
||||
|
||||
return dao.deleteCollection(collection);
|
||||
}, (db) => {
|
||||
const collection = unmarshal(%s, new Collection());
|
||||
const collection = new Collection(%s);
|
||||
|
||||
return Dao(db).saveCollection(collection);
|
||||
})
|
||||
@@ -222,7 +222,7 @@ func (p *plugin) jsDiffTemplate(new *models.Collection, old *models.Collection)
|
||||
upParts = append(upParts, fmt.Sprintf("%s.schema.removeField(%q)\n", varName, oldField.Id))
|
||||
|
||||
downParts = append(downParts, "// add")
|
||||
downParts = append(downParts, fmt.Sprintf("%s.schema.addField(unmarshal(%s, new SchemaField()))\n", varName, rawOldField))
|
||||
downParts = append(downParts, fmt.Sprintf("%s.schema.addField(new SchemaField(%s))\n", varName, rawOldField))
|
||||
}
|
||||
|
||||
// created fields
|
||||
@@ -237,7 +237,7 @@ func (p *plugin) jsDiffTemplate(new *models.Collection, old *models.Collection)
|
||||
}
|
||||
|
||||
upParts = append(upParts, "// add")
|
||||
upParts = append(upParts, fmt.Sprintf("%s.schema.addField(unmarshal(%s, new SchemaField()))\n", varName, rawNewField))
|
||||
upParts = append(upParts, fmt.Sprintf("%s.schema.addField(new SchemaField(%s))\n", varName, rawNewField))
|
||||
|
||||
downParts = append(downParts, "// remove")
|
||||
downParts = append(downParts, fmt.Sprintf("%s.schema.removeField(%q)\n", varName, newField.Id))
|
||||
@@ -265,10 +265,10 @@ func (p *plugin) jsDiffTemplate(new *models.Collection, old *models.Collection)
|
||||
}
|
||||
|
||||
upParts = append(upParts, "// update")
|
||||
upParts = append(upParts, fmt.Sprintf("%s.schema.addField(unmarshal(%s, new SchemaField()))\n", varName, rawNewField))
|
||||
upParts = append(upParts, fmt.Sprintf("%s.schema.addField(new SchemaField(%s))\n", varName, rawNewField))
|
||||
|
||||
downParts = append(downParts, "// update")
|
||||
downParts = append(downParts, fmt.Sprintf("%s.schema.addField(unmarshal(%s, new SchemaField()))\n", varName, rawOldField))
|
||||
downParts = append(downParts, fmt.Sprintf("%s.schema.addField(new SchemaField(%s))\n", varName, rawOldField))
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user