From e5ece787d1eff7c4e866a62ee0940ae88e4ba221 Mon Sep 17 00:00:00 2001 From: Sergey Vershinin Date: Wed, 27 Dec 2023 01:43:06 +0300 Subject: [PATCH] feat: auto detect YAML format based on key suffix --- backend/services/browser_service.go | 32 +++++++++---------- backend/types/view_type.go | 1 + backend/utils/string/convert.go | 16 +++++++--- .../content_value/ContentEntryEditor.vue | 3 ++ .../content_value/ContentValueString.vue | 3 ++ frontend/src/consts/value_view_type.js | 1 + frontend/src/stores/browser.js | 5 +-- 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/backend/services/browser_service.go b/backend/services/browser_service.go index 50feb11..8f34a1f 100644 --- a/backend/services/browser_service.go +++ b/backend/services/browser_service.go @@ -736,7 +736,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS Value: val, }) if doConvert { - if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { + if dv, _, _ := strutil.ConvertTo(key, val, param.Decode, param.Format); dv != val { items[len(items)-1].DisplayValue = dv } } @@ -782,7 +782,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS Value: strutil.EncodeRedisKey(loadedVal[i+1]), }) if doConvert { - if dv, _, _ := strutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] { + if dv, _, _ := strutil.ConvertTo(key, loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] { items[len(items)-1].DisplayValue = dv } } @@ -807,7 +807,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS items[i/2].Key = loadedVal[i] items[i/2].Value = strutil.EncodeRedisKey(loadedVal[i+1]) if doConvert { - if dv, _, _ := strutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] { + if dv, _, _ := strutil.ConvertTo(key, loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] { items[i/2].DisplayValue = dv } } @@ -851,7 +851,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS Value: val, }) if doConvert { - if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { + if dv, _, _ := strutil.ConvertTo(key, val, param.Decode, param.Format); dv != val { items[len(items)-1].DisplayValue = dv } } @@ -871,7 +871,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS for i, val := range loadedKey { items[i].Value = val if doConvert { - if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { + if dv, _, _ := strutil.ConvertTo(key, val, param.Decode, param.Format); dv != val { items[i].DisplayValue = dv } } @@ -918,7 +918,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS Score: score, }) if doConvert { - if dv, _, _ := strutil.ConvertTo(loadedVal[i], param.Decode, param.Format); dv != loadedVal[i] { + if dv, _, _ := strutil.ConvertTo(key, loadedVal[i], param.Decode, param.Format); dv != loadedVal[i] { items[len(items)-1].DisplayValue = dv } } @@ -952,7 +952,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS Value: val, }) if doConvert { - if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { + if dv, _, _ := strutil.ConvertTo(key, val, param.Decode, param.Format); dv != val { items[len(items)-1].DisplayValue = dv } } @@ -1013,7 +1013,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS if vb, merr := json.Marshal(msg.Values); merr != nil { it.DisplayValue = "{}" } else { - it.DisplayValue, _, _ = strutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON) + it.DisplayValue, _, _ = strutil.ConvertTo(key, string(vb), types.DECODE_NONE, types.FORMAT_JSON) } if doFilter && !strings.Contains(it.DisplayValue, param.MatchPattern) { continue @@ -1045,9 +1045,9 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS // ConvertValue convert value with decode method and format // blank decode indicate auto decode // blank format indicate auto format -func (b *browserService) ConvertValue(value any, decode, format string) (resp types.JSResp) { +func (b *browserService) ConvertValue(key string, value any, decode, format string) (resp types.JSResp) { str := strutil.DecodeRedisKey(value) - value, decode, format = strutil.ConvertTo(str, decode, format) + value, decode, format = strutil.ConvertTo(key, str, decode, format) resp.Success = true resp.Data = map[string]any{ "value": value, @@ -1206,7 +1206,7 @@ func (b *browserService) SetHashValue(param types.SetHashParam) (resp types.JSRe return } if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 { - displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat) + displayStr, _, _ = strutil.ConvertTo(key, saveStr, param.RetDecode, param.RetFormat) } var updated, added, removed []types.HashEntryItem var replaced []types.HashReplaceItem @@ -1435,7 +1435,7 @@ func (b *browserService) SetListItem(param types.SetListParam) (resp types.JSRes } var displayStr string if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 { - displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat) + displayStr, _, _ = strutil.ConvertTo(key, saveStr, param.RetDecode, param.RetFormat) } replaced = append(replaced, types.ListReplaceItem{ Index: param.Index, @@ -1534,7 +1534,7 @@ func (b *browserService) UpdateSetItem(param types.SetSetParam) (resp types.JSRe // add new item var displayStr string if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 { - displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat) + displayStr, _, _ = strutil.ConvertTo(key, saveStr, param.RetDecode, param.RetFormat) } added = append(added, types.SetEntryItem{ Value: saveStr, @@ -1591,7 +1591,7 @@ func (b *browserService) UpdateZSetValue(param types.SetZSetParam) (resp types.J Score: param.Score, Member: saveVal, }).Result() - displayValue, _, _ := strutil.ConvertTo(val, param.RetDecode, param.RetFormat) + displayValue, _, _ := strutil.ConvertTo(key, val, param.RetDecode, param.RetFormat) if affect > 0 { // add new item added = append(added, types.ZSetEntryItem{ @@ -1619,7 +1619,7 @@ func (b *browserService) UpdateZSetValue(param types.SetZSetParam) (resp types.J Score: param.Score, Member: saveVal, }).Result() - displayValue, _, _ := strutil.ConvertTo(saveVal, param.RetDecode, param.RetFormat) + displayValue, _, _ := strutil.ConvertTo(key, saveVal, param.RetDecode, param.RetFormat) if affect <= 0 { // no new value added, just update exists item removed = append(removed, types.ZSetEntryItem{ @@ -1745,7 +1745,7 @@ func (b *browserService) AddStreamValue(connName string, db int, k any, ID strin updateValues[fieldItems[i].(string)] = fieldItems[i+1] } vb, _ := json.Marshal(updateValues) - displayValue, _, _ := strutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON) + displayValue, _, _ := strutil.ConvertTo(key, string(vb), types.DECODE_NONE, types.FORMAT_JSON) resp.Success = true resp.Data = struct { diff --git a/backend/types/view_type.go b/backend/types/view_type.go index f4fe4ad..997b178 100644 --- a/backend/types/view_type.go +++ b/backend/types/view_type.go @@ -2,6 +2,7 @@ package types const FORMAT_RAW = "Raw" const FORMAT_JSON = "JSON" +const FORMAT_YAML = "YAML" const FORMAT_HEX = "Hex" const FORMAT_BINARY = "Binary" diff --git a/backend/utils/string/convert.go b/backend/utils/string/convert.go index 437f913..c13eb54 100644 --- a/backend/utils/string/convert.go +++ b/backend/utils/string/convert.go @@ -21,7 +21,7 @@ import ( // ConvertTo convert string to specified type // @param decodeType empty string indicates automatic detection // @param formatType empty string indicates automatic detection -func ConvertTo(str, decodeType, formatType string) (value, resultDecode, resultFormat string) { +func ConvertTo(key, str, decodeType, formatType string) (value, resultDecode, resultFormat string) { if len(str) <= 0 { // empty content if len(formatType) <= 0 { @@ -40,7 +40,7 @@ func ConvertTo(str, decodeType, formatType string) (value, resultDecode, resultF // decode first value, resultDecode = decodeWith(str, decodeType) // then format content - value, resultFormat = viewAs(value, formatType) + value, resultFormat = viewAs(key, value, formatType) return } @@ -145,7 +145,7 @@ func autoDecode(str string) (value, resultDecode string) { return } -func viewAs(str, formatType string) (value, resultFormat string) { +func viewAs(key string, str, formatType string) (value, resultFormat string) { if len(formatType) > 0 { switch formatType { case types.FORMAT_RAW: @@ -182,12 +182,12 @@ func viewAs(str, formatType string) (value, resultFormat string) { } } - return autoViewAs(str) + return autoViewAs(key, str) } // attempt automatic convert to possible types // if no conversion is possible, it will return the origin string value and "plain text" type -func autoViewAs(str string) (value, resultFormat string) { +func autoViewAs(key string, str string) (value, resultFormat string) { if len(str) > 0 { var ok bool if value, ok = decodeJson(str); ok { @@ -201,6 +201,12 @@ func autoViewAs(str string) (value, resultFormat string) { return } } + + if strings.HasSuffix(key, ".yaml") { + value = str + resultFormat = types.FORMAT_YAML + return + } } value = str diff --git a/frontend/src/components/content_value/ContentEntryEditor.vue b/frontend/src/components/content_value/ContentEntryEditor.vue index 37bf770..d356a50 100644 --- a/frontend/src/components/content_value/ContentEntryEditor.vue +++ b/frontend/src/components/content_value/ContentEntryEditor.vue @@ -97,6 +97,8 @@ const viewLanguage = computed(() => { switch (viewAs.format) { case formatTypes.JSON: return 'json' + case formatTypes.YAML: + return 'yaml' default: return 'plaintext' } @@ -116,6 +118,7 @@ const onFormatChanged = async (decode = null, format = null) => { decode: retDecode, format: retFormat, } = await browserStore.convertValue({ + key: props.field, value: props.value, decode, format, diff --git a/frontend/src/components/content_value/ContentValueString.vue b/frontend/src/components/content_value/ContentValueString.vue index 64ba1da..61dd653 100644 --- a/frontend/src/components/content_value/ContentValueString.vue +++ b/frontend/src/components/content_value/ContentValueString.vue @@ -53,6 +53,8 @@ const viewLanguage = computed(() => { switch (viewAs.format) { case formatTypes.JSON: return 'json' + case formatTypes.YAML: + return 'yaml' default: return 'plaintext' } @@ -94,6 +96,7 @@ const onFormatChanged = async (decode = '', format = '') => { decode: retDecode, format: retFormat, } = await browserStore.convertValue({ + key: keyName.value, value: props.value, decode, format, diff --git a/frontend/src/consts/value_view_type.js b/frontend/src/consts/value_view_type.js index fe60a91..33e6ac2 100644 --- a/frontend/src/consts/value_view_type.js +++ b/frontend/src/consts/value_view_type.js @@ -7,6 +7,7 @@ export const formatTypes = { JSON: 'JSON', // XML: 'XML', // YML: 'YML', + YAML: 'YAML', HEX: 'Hex', BINARY: 'Binary', } diff --git a/frontend/src/stores/browser.js b/frontend/src/stores/browser.js index ed57691..ff3aec8 100644 --- a/frontend/src/stores/browser.js +++ b/frontend/src/stores/browser.js @@ -570,14 +570,15 @@ const useBrowserStore = defineStore('browser', { /** * convert value by decode type or format + * @param {string} key * @param {string|number[]} value * @param {string} [decode] * @param {string} [format] * @return {Promise<{[format]: string, [decode]: string, value: string}>} */ - async convertValue({ value, decode, format }) { + async convertValue({ key, value, decode, format }) { try { - const { data, success } = await ConvertValue(value, decode, format) + const { data, success } = await ConvertValue( key, value, decode, format) if (success) { const { value: retVal, decode: retDecode, format: retFormat } = data return { value: retVal, decode: retDecode, format: retFormat }