func NewRecord(templateRecordUid string, records []*Record, newRecordUid string) (*Record, error) {
	templateRecord, err := findTemplateRecord(templateRecordUid, records)
	if err != nil {
		return nil, err
	}

	recordKeyBytes, _ := GetRandomBytes(32)
	folderKeyBytesCopy := make([]byte, len(templateRecord.folderKeyBytes))
	copy(folderKeyBytesCopy, templateRecord.folderKeyBytes)

	// copy and preserve known keys but clear all other values except record type
	// drop custom[] and any other unknown top-level keys
	recordDictCopy := CopyableMap(templateRecord.RecordDict).DeepCopy()
	for key, val := range recordDictCopy {
		switch key {
		case "type":
			continue
		case "title", "notes":
			recordDictCopy[key] = ""
		case "custom":
			delete(recordDictCopy, key)
		case "fields":
			if fslice, ok := val.([]interface{}); ok {
				for _, fs := range fslice {
					if fmap, ok := fs.(map[string]interface{}); ok {
						for fkey := range fmap {
							// preserve field type, clear label and value, drop everything else
							switch fkey {
							case "type":
								continue
							case "label":
								fmap[fkey] = ""
							case "value":
								fmap[fkey] = []interface{}{}
							default:
								klog.Warning("create new record - removing field type property", key)
								delete(fmap, key)
							}
						}
					} else {
						klog.Warning("create new record - fields type is not in the expected format and is removed")
					}
				}
			} else {
				klog.Warning("create new record - fields[] is not in the expected format and is replaced")
				recordDictCopy[key] = []interface{}{}
			}
		default:
			klog.Warning("create new record - removing unknown record type property", key)
			delete(recordDictCopy, key)
		}
	}
	rawJson := DictToJson(recordDictCopy)

	recordUid := GenerateUid()
	if ruid := strings.TrimSpace(newRecordUid); ruid != "" {
		if numBytes := len(Base64ToBytes(ruid)); numBytes == 16 {
			recordUid = newRecordUid
		}
	}
	if newRecordUid != "" && recordUid != newRecordUid {
		klog.Warning("invalid new record UID provided:", newRecordUid, " - using autogenerated UID:", recordUid)
	}

	rec := &Record{
		RecordKeyBytes: recordKeyBytes,
		Uid:            recordUid,
		folderKeyBytes: folderKeyBytesCopy,
		folderUid:      templateRecord.folderUid,
		Files:          []*KeeperFile{},
		Revision:       templateRecord.Revision,
		IsEditable:     templateRecord.IsEditable,
		recordType:     templateRecord.recordType,
		RawJson:        rawJson,
		RecordDict:     recordDictCopy,
	}

	return rec, nil
}
// NewRecord returns a new empty record of the same type as template object but with new UID and RecordKeyBytes
// generates and uses new random UID if newRecordUid is empty
// returns error if template record is not found
NewRecord returns a new empty record of the same type as template object but with new UID and RecordKeyBytes
generates and uses new random UID if newRecordUid is empty
returns error if template record is not found
// NewRecord returns a new empty record of the same type as template object but with new UID and RecordKeyBytes // generates and uses new random UID if newRecordUid is empty // returns error if template record is not found
func NewRecord(templateRecordUid string, records []*Record, newRecordUid string) (*Record, error) {
	templateRecord, err := findTemplateRecord(templateRecordUid, records)
	if err != nil {
		return nil, err
	}
	recordKeyBytes, _ := GetRandomBytes(32)
	folderKeyBytesCopy := make([]byte, len(templateRecord.folderKeyBytes))
	copy(folderKeyBytesCopy, templateRecord.folderKeyBytes)
	recordDictCopy := CopyableMap(templateRecord.RecordDict).DeepCopy()
	for key, val := range recordDictCopy {
		switch key {
		case "type":
			continue
		case "title", "notes":
			recordDictCopy[key] = ""
		case "custom":
			delete(recordDictCopy, key)
		case "fields":
			if fslice, ok := val.([]interface{}); ok {
				for _, fs := range fslice {
					if fmap, ok := fs.(map[string]interface{}); ok {
						for fkey := range fmap {
							switch fkey {
							case "type":
								continue
							case "label":
								fmap[fkey] = ""
							case "value":
								fmap[fkey] = []interface{}{}
							default:
								klog.Warning("create new record - removing field type property", key)
								delete(fmap, key)
							}
						}
					} else {
						klog.Warning("create new record - fields type is not in the expected format and is removed")
					}
				}
			} else {
				klog.Warning("create new record - fields[] is not in the expected format and is replaced")
				recordDictCopy[key] = []interface{}{}
			}
		default:
			klog.Warning("create new record - removing unknown record type property", key)
			delete(recordDictCopy, key)
		}
	}
	rawJson := DictToJson(recordDictCopy)
	recordUid := GenerateUid()
	if ruid := strings.TrimSpace(newRecordUid); ruid != "" {
		if numBytes := len(Base64ToBytes(ruid)); numBytes == 16 {
			recordUid = newRecordUid
		}
	}
	if newRecordUid != "" && recordUid != newRecordUid {
		klog.Warning("invalid new record UID provided:", newRecordUid, " - using autogenerated UID:", recordUid)
	}
	rec := &Record{
		RecordKeyBytes: recordKeyBytes,
		Uid:            recordUid,
		folderKeyBytes: folderKeyBytesCopy,
		folderUid:      templateRecord.folderUid,
		Files:          []*KeeperFile{},
		Revision:       templateRecord.Revision,
		IsEditable:     templateRecord.IsEditable,
		recordType:     templateRecord.recordType,
		RawJson:        rawJson,
		RecordDict:     recordDictCopy,
	}
	return rec, nil
}
func NewRecord ( templateRecordUid string , records [ ] * Record , newRecordUid string ) ( * Record , error ) { templateRecord , err := findTemplateRecord ( templateRecordUid , records ) if err != nil { return nil , err } recordKeyBytes , _ := GetRandomBytes ( 32 ) folderKeyBytesCopy := make ( [ ] byte , len ( templateRecord . folderKeyBytes ) ) copy ( folderKeyBytesCopy , templateRecord . folderKeyBytes ) recordDictCopy := CopyableMap ( templateRecord . RecordDict ) . DeepCopy ( ) for key , val := range recordDictCopy { switch key { case " " : continue case " " , " " : recordDictCopy [ key ] = " " case " " : delete ( recordDictCopy , key ) case " " : if fslice , ok := val . ( [ ] interface { } ) ; ok { for _ , fs := range fslice { if fmap , ok := fs . ( map [ string ] interface { } ) ; ok { for fkey := range fmap { switch fkey { case " " : continue case " " : fmap [ fkey ] = " " case " " : fmap [ fkey ] = [ ] interface { } { } default : klog . Warning ( " " , key ) delete ( fmap , key ) } } } else { klog . Warning ( " " ) } } } else { klog . Warning ( " " ) recordDictCopy [ key ] = [ ] interface { } { } } default : klog . Warning ( " " , key ) delete ( recordDictCopy , key ) } } rawJson := DictToJson ( recordDictCopy ) recordUid := GenerateUid ( ) if ruid := strings . TrimSpace ( newRecordUid ) ; ruid != " " { if numBytes := len ( Base64ToBytes ( ruid ) ) ; numBytes == 16 { recordUid = newRecordUid } } if newRecordUid != " " && recordUid != newRecordUid { klog . Warning ( " " , newRecordUid , " " , recordUid ) } rec := & Record { RecordKeyBytes : recordKeyBytes , Uid : recordUid , folderKeyBytes : folderKeyBytesCopy , folderUid : templateRecord . folderUid , Files : [ ] * KeeperFile { } , Revision : templateRecord . Revision , IsEditable : templateRecord . IsEditable , recordType : templateRecord . recordType , RawJson : rawJson , RecordDict : recordDictCopy , } return rec , nil }
NewRecord returns a new empty record of the same type as template object but with new UID and RecordKeyBytes
generates and uses new random UID if newRecordUid is empty
returns error if template record is not found
NewRecord returns a new empty record of the same type as template object but with new UID and RecordKeyBytes generates and uses new random UID if newRecordUid is empty returns error if template record is not found
// copy and preserve known keys but clear all other values except record type // drop custom[] and any other unknown top-level keys // preserve field type, clear label and value, drop everything else