feat: custom formatter support
- format.ts: customFormat() uses child_process.execFile
- Template params: {KEY} {VALUE} {HEX_FILE}
- Value written to temp file, path passed via {HEX_FILE}
- 10s timeout, error handling
- StringEditor: 'custom' format option + command input
- Command persisted to localStorage
- i18n keys (zh-CN + en)
This commit is contained in:
@@ -34,8 +34,11 @@ const formatOptions = [
|
||||
{ value: 'gzip', labelKey: 'editor.formatGzip' },
|
||||
{ value: 'deflate', labelKey: 'editor.formatDeflate' },
|
||||
{ value: 'brotli', labelKey: 'editor.formatBrotli' },
|
||||
{ value: 'custom', labelKey: 'editor.formatCustom' },
|
||||
]
|
||||
|
||||
const customCommand = ref(localStorage.getItem('customFormatter') || '/bin/cat {HEX_FILE}')
|
||||
|
||||
const effectiveFormat = computed(() => {
|
||||
if (selectedFormat.value === 'auto') return detectedFormat.value
|
||||
return selectedFormat.value
|
||||
@@ -70,6 +73,11 @@ async function decodeAndDisplay(raw: string) {
|
||||
}
|
||||
}
|
||||
// For other formats, use IPC decode
|
||||
if (fmt === 'custom') {
|
||||
displayValue.value = await window.electronAPI.redis.customFormat(raw, customCommand.value, keyStore.selectedKey || '')
|
||||
isJson.value = false
|
||||
return
|
||||
}
|
||||
displayValue.value = await window.electronAPI.redis.decodeValue(raw, fmt)
|
||||
isJson.value = false
|
||||
}
|
||||
@@ -90,6 +98,8 @@ watch(selectedFormat, () => {
|
||||
if (editedValue.value) decodeAndDisplay(editedValue.value)
|
||||
})
|
||||
|
||||
watch(customCommand, (v) => localStorage.setItem('customFormatter', v))
|
||||
|
||||
const editorOptions = computed(() => ({
|
||||
readOnly: !isEditing.value || effectiveFormat.value !== 'json' && effectiveFormat.value !== 'text',
|
||||
minimap: { enabled: false },
|
||||
@@ -133,6 +143,13 @@ async function save() {
|
||||
:label="t(opt.labelKey)"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="selectedFormat === 'custom'"
|
||||
v-model="customCommand"
|
||||
size="small"
|
||||
style="width:240px"
|
||||
:placeholder="t('editor.customCommandHint')"
|
||||
/>
|
||||
<span v-if="selectedFormat === 'auto'" class="format-detected">
|
||||
{{ t('editor.format') }}: {{ detectedFormat }}
|
||||
</span>
|
||||
|
||||
@@ -141,6 +141,9 @@ export default {
|
||||
formatGzip: 'Gzip',
|
||||
formatDeflate: 'Deflate',
|
||||
formatBrotli: 'Brotli',
|
||||
formatCustom: 'Custom',
|
||||
customCommand: 'Custom Command',
|
||||
customCommandHint: 'Templates: {KEY} {VALUE} {HEX_FILE}',
|
||||
consumerGroups: 'Consumer Groups',
|
||||
group: 'Group',
|
||||
consumers: 'Consumers',
|
||||
|
||||
@@ -141,6 +141,9 @@ export default {
|
||||
formatGzip: 'Gzip',
|
||||
formatDeflate: 'Deflate',
|
||||
formatBrotli: 'Brotli',
|
||||
formatCustom: '自定义',
|
||||
customCommand: '自定义命令',
|
||||
customCommandHint: '模板: {KEY} {VALUE} {HEX_FILE}',
|
||||
consumerGroups: '消费者组',
|
||||
group: '组名',
|
||||
consumers: '消费者',
|
||||
|
||||
Reference in New Issue
Block a user