diff --git a/src/legacy/core_plugins/console/public/src/autocomplete.js b/src/legacy/core_plugins/console/public/src/autocomplete.js index 8275813ea2b98..a29854ee2a02a 100644 --- a/src/legacy/core_plugins/console/public/src/autocomplete.js +++ b/src/legacy/core_plugins/console/public/src/autocomplete.js @@ -345,7 +345,14 @@ export default function (editor) { let valueToInsert = termAsString; let templateInserted = false; if (context.addTemplate && !_.isUndefined(term.template) && !_.isNull(term.template)) { - const indentedTemplateLines = utils.jsonToString(term.template, true).split('\n'); + let indentedTemplateLines; + // In order to allow triple quoted strings in template completion we check the `__raw_` + // attribute to determine whether this template should go through JSON formatting. + if (term.template.__raw && term.template.value) { + indentedTemplateLines = term.template.value.split('\n'); + } else { + indentedTemplateLines = utils.jsonToString(term.template, true).split('\n'); + } let currentIndentation = session.getLine(context.rangeToReplace.start.row); currentIndentation = currentIndentation.match(/^\s*/)[0]; for (let i = 1; i < indentedTemplateLines.length; i++) // skip first line diff --git a/src/legacy/core_plugins/console/public/src/autocomplete/body_completer.js b/src/legacy/core_plugins/console/public/src/autocomplete/body_completer.js index 68e0889f9c618..e377a749aaf78 100644 --- a/src/legacy/core_plugins/console/public/src/autocomplete/body_completer.js +++ b/src/legacy/core_plugins/console/public/src/autocomplete/body_completer.js @@ -127,6 +127,18 @@ class ScopeResolver extends SharedComponent { } function getTemplate(description) { if (description.__template) { + if (description.__raw && _.isString(description.__template)) { + return { + // This is a special secret attribute that gets passed through to indicate that + // the raw value should be passed through to the console without JSON.stringifying it + // first. + // + // Primary use case is to allow __templates to contain extended JSON special values like + // triple quotes. + __raw: true, + value: description.__template, + }; + } return description.__template; } else if (description.__one_of) { return getTemplate(description.__one_of[0]); diff --git a/src/legacy/core_plugins/console/public/src/utils.js b/src/legacy/core_plugins/console/public/src/utils.js index 1f2c3b9267b74..15a32f90942a2 100644 --- a/src/legacy/core_plugins/console/public/src/utils.js +++ b/src/legacy/core_plugins/console/public/src/utils.js @@ -59,9 +59,11 @@ utils.reformatData = function (data, indent) { }; utils.collapseLiteralStrings = function (data) { - return data.replace(/"""(?:\s*\r?\n)?((?:.|\r?\n)*?)(?:\r?\n\s*)?"""/g, function (match, literal) { - return JSON.stringify(literal); - }); + const splitData = data.split(`"""`); + for (let idx = 1; idx < splitData.length - 1; idx += 2) { + splitData[idx] = JSON.stringify(splitData[idx]); + } + return splitData.join(''); }; utils.expandLiteralStrings = function (data) { @@ -69,8 +71,7 @@ utils.expandLiteralStrings = function (data) { // expand things with two slashes or more if (string.split(/\\./).length > 2) { string = JSON.parse(string).replace('^\s*\n', '').replace('\n\s*^', ''); - const append = string.includes('\n') ? '\n' : ''; // only go multi line if the string has multiline - return '"""' + append + string + append + '"""'; + return '"""' + string + '"""'; } else { return string; } diff --git a/src/legacy/core_plugins/console/public/tests/src/utils_string_collapsing.txt b/src/legacy/core_plugins/console/public/tests/src/utils_string_collapsing.txt index 235151317377f..5ddd1b5a376fe 100644 --- a/src/legacy/core_plugins/console/public/tests/src/utils_string_collapsing.txt +++ b/src/legacy/core_plugins/console/public/tests/src/utils_string_collapsing.txt @@ -8,11 +8,11 @@ to you """ ========== String only 2 ------------------------------------- -""" +""" starting with new lines and ending as well - """ +""" ------------------------------------- -"starting with new lines and ending as well" +"\nstarting with new lines and ending as well\n" ========== Strings in requests ------------------------------------- @@ -27,8 +27,8 @@ test2 } ------------------------------------- { - "f": { "somefield" : "test\ntest2" }, + "f": { "somefield" : "\ntest\ntest2\n" }, "g": { "script" : "second + \"\\\";" }, "h": 1, "script": "a + 2" -} \ No newline at end of file +} diff --git a/src/legacy/core_plugins/console/public/tests/src/utils_string_expanding.txt b/src/legacy/core_plugins/console/public/tests/src/utils_string_expanding.txt index 762e0ad164634..4f3abf177490a 100644 --- a/src/legacy/core_plugins/console/public/tests/src/utils_string_expanding.txt +++ b/src/legacy/core_plugins/console/public/tests/src/utils_string_expanding.txt @@ -2,7 +2,7 @@ Scripts in requests ------------------------------------- { - "f": { "script" : { "source": "test\ntest\\2" } }, + "f": { "script" : { "source": "\ntest\ntest\\2\n" } }, "g": { "script" : "second + \"\\\";" }, "f": "short with \\", "h": 1, diff --git a/x-pack/legacy/plugins/console_extensions/spec/overrides/sql.query.json b/x-pack/legacy/plugins/console_extensions/spec/overrides/sql.query.json new file mode 100644 index 0000000000000..f2fe456a0c6e2 --- /dev/null +++ b/x-pack/legacy/plugins/console_extensions/spec/overrides/sql.query.json @@ -0,0 +1,23 @@ +{ + "sql.query": { + "data_autocomplete_rules": { + "query": { + "__template": { + "__raw": true, + "value": "\"\"\"\nSELECT * FROM \"TABLE\"\n\"\"\"" + } + } + }, + "url_params": { + "format": [ + "csv", + "json", + "tsv", + "txt", + "yaml", + "cbor", + "smile" + ] + } + } +}