diff --git a/packages/api/src/shell/jsonWriter.js b/packages/api/src/shell/jsonWriter.js index d80f343be..3dcb4fc63 100644 --- a/packages/api/src/shell/jsonWriter.js +++ b/packages/api/src/shell/jsonWriter.js @@ -1,17 +1,22 @@ const { getLogger } = require('dbgate-tools'); const fs = require('fs'); const stream = require('stream'); +const _ = require('lodash'); const logger = getLogger('jsonArrayWriter'); class StringifyStream extends stream.Transform { - constructor() { + constructor({ jsonStyle, keyField, rootField }) { super({ objectMode: true }); this.wasHeader = false; this.wasRecord = false; + this.jsonStyle = jsonStyle; + this.keyField = keyField; + this.rootField = rootField; } _transform(chunk, encoding, done) { let skip = false; + const keyField = this.keyField || '_key'; if (!this.wasHeader) { skip = chunk.__isStreamHeader; @@ -19,30 +24,71 @@ class StringifyStream extends stream.Transform { } if (!skip) { if (!this.wasRecord) { - this.push('[\n'); + if (this.rootField) { + if (this.jsonStyle === 'object') { + this.push(`{"${this.rootField}": {\n`); + } else { + this.push(`{"${this.rootField}": [\n`); + } + } else { + if (this.jsonStyle === 'object') { + this.push('{\n'); + } else { + this.push('[\n'); + } + } } else { this.push(',\n'); } this.wasRecord = true; - this.push(JSON.stringify(chunk)); + if (this.jsonStyle === 'object') { + const key = chunk[keyField] ?? chunk[Object.keys(chunk)[0]]; + this.push(`"${key}": ${JSON.stringify(_.omit(chunk, [keyField]))}`); + } else { + this.push(JSON.stringify(chunk)); + } } done(); } _flush(done) { if (!this.wasRecord) { - this.push('[]\n'); + if (this.rootField) { + if (this.jsonStyle === 'object') { + this.push(`{"${this.rootField}": {}}\n`); + } else { + this.push(`{"${this.rootField}": []}\n`); + } + } else { + if (this.jsonStyle === 'object') { + this.push('{}\n'); + } else { + this.push('[]\n'); + } + } } else { - this.push('\n]\n'); + if (this.rootField) { + if (this.jsonStyle === 'object') { + this.push('\n}}\n'); + } else { + this.push('\n]}\n'); + } + } else { + if (this.jsonStyle === 'object') { + this.push('\n}\n'); + } else { + this.push('\n]\n'); + } + } } done(); } } -async function jsonWriter({ fileName, encoding = 'utf-8' }) { +async function jsonWriter({ fileName, jsonStyle, keyField, rootField, encoding = 'utf-8' }) { logger.info(`Writing file ${fileName}`); - const stringify = new StringifyStream(); + const stringify = new StringifyStream({ jsonStyle, keyField, rootField }); const fileStream = fs.createWriteStream(fileName, encoding); stringify.pipe(fileStream); stringify['finisher'] = fileStream; diff --git a/packages/web/src/plugins/fileformats.ts b/packages/web/src/plugins/fileformats.ts index 34b26ae6e..94b49411e 100644 --- a/packages/web/src/plugins/fileformats.ts +++ b/packages/web/src/plugins/fileformats.ts @@ -22,19 +22,19 @@ const jsonFormat = { name: 'jsonStyle', label: 'JSON style', options: [ - { name: 'Array', value: 'array' }, + { name: 'Array', value: '' }, { name: 'Object', value: 'object' }, ], apiName: 'jsonStyle', }, { - type: 'textbox', + type: 'text', name: 'keyField', - label: 'Key field', + label: 'Key field (only for "Object" style)', apiName: 'keyField', }, { - type: 'textbox', + type: 'text', name: 'rootField', label: 'Root field', apiName: 'rootField',