UNPKG

@catladder/pipeline

Version:

Panter workflow for cloud CI/CD and DevOps

127 lines (126 loc) 5.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.escapeForDotEnv = exports.escapeNewlines = exports.escapeBackTicks = exports.escapeSingleQuotes = exports.escapeDoubleQuotes = exports.escapeBashExpression = exports.escapeString = exports.bashEscape = void 0; var globalScriptFunctions_1 = require("../globalScriptFunctions"); var VariableValueContainingReferences_1 = require("../variables/VariableValueContainingReferences"); var BashExpression_1 = require("./BashExpression"); /** * escapes a string or bash expression for bash * it either can escape single or double quotes (double is default) */ var bashEscape = function (value, options) { if (options === void 0) { options = { quotes: "double" }; } if (value instanceof BashExpression_1.BashExpression) { // no need to escape return (0, exports.escapeBashExpression)(value, options); } if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) { return value.toString(options); } return (0, exports.escapeString)(value, options); }; exports.bashEscape = bashEscape; var escapeString = function (value, _a) { var _b = _a === void 0 ? { quotes: "double" } : _a, quotes = _b.quotes; var quoteEscaped = quotes ? quotes === "single" ? (0, exports.escapeSingleQuotes)(value) : (0, exports.escapeDoubleQuotes)(value) : value; return quoteEscaped; }; exports.escapeString = escapeString; var escapeBashExpression = function (value, options) { // no need to escape, we just return the string return value; }; exports.escapeBashExpression = escapeBashExpression; var escapeDoubleQuotes = function (value) { return value === null || value === void 0 ? void 0 : value.toString().replace(/"/g, '\\"'); }; exports.escapeDoubleQuotes = escapeDoubleQuotes; var escapeSingleQuotes = function (value) { return value === null || value === void 0 ? void 0 : value.toString().replace(/'/g, "\\'"); }; exports.escapeSingleQuotes = escapeSingleQuotes; var escapeBackTicks = function (value) { return value === null || value === void 0 ? void 0 : value.toString().replace(/`/g, "\\`"); }; exports.escapeBackTicks = escapeBackTicks; var escapeNewlines = function (value) { return value === null || value === void 0 ? void 0 : value.toString().replace(/\n/g, "\\n"); }; exports.escapeNewlines = escapeNewlines; /** * * escape env vars for .env files. * unfortunatly, the format has many limitations. In order to be very forgiving, we need to do some magic here: * * - when the value contains no newlines, we are fine * - if the value contains newlines, we need to wrap it in quotes. And thats where the problem begins: * - you can't escape quotes. this is a limitation of dotenv and node * - you can have inner quotes, but they break in node.js (not in dotenv though), see https://github.com/nodejs/node/issues/54134 * - so we need to quote cleverly * - to make things worse, we need to check whether we have a simple stirng or a bash expression, that needs to be evalulated first... * * what an absolute nightmare. * * - other languages are currently only partially supported, since most .env implementations are slightly different */ var escapeForDotEnv = function (value, options) { if (options === void 0) { options = { quoteMode: "auto" }; } if (value === undefined || value === null) { return ""; } if (typeof value === "string") { // if string contains newlines, we need to wrap it in quotes // we additionaly escape newlines, that give best compatibility if (options.quoteMode === "always" || value.includes("\n")) { var newlinesReplaces = value.replace(/\n/g, "\\n"); // default to ", but if this is not possible, we try to use ' or ` var quote = value.includes("\"") ? value.includes("'") ? value.includes("`") ? // If all quote types are present, default to double quotes. This works in dotenv, but not in node.js because of the bug mentioned abouve '"' : "`" : "'" : '"'; // if we found a quote, we can wrap the string in it return "".concat(quote).concat(newlinesReplaces).concat(quote); } else { // otherwise we can return as is return value; } } else if (value instanceof BashExpression_1.BashExpression) { return escapeBashExpressionForDotEnv(value); } else if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) { // instead of doing it part-wise, we just do it all at once var containsAnyBashExpression = value.parts.some(function (part) { return part instanceof BashExpression_1.BashExpression; }); if (!containsAnyBashExpression) { return (0, exports.escapeForDotEnv)(value.toString({ quotes: "double" })); } else { var result = escapeBashExpressionForDotEnv(new BashExpression_1.BashExpression(value.toString({ quotes: "double" }))); return result; } } else { return value; } }; exports.escapeForDotEnv = escapeForDotEnv; // basically the same thing as above for bash // thx chatgpt for this var escapeForDotEnvScript = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("escapeForDotEnv", "\n input=\"${1:-$(cat)}\"\n input=\"${input//$'\\n'/\\\\n}\"\n if [[ \"$input\" == *\\\\n* ]]; then\n if [[ \"$input\" == *\\\"* && \"$input\" == *\\'* && \"$input\" == *\\`* ]]; then\n printf \"\\\"%s\\\"\\n\" \"$input\" ".concat( /* fallback to double quotes */"", "\n elif [[ \"$input\" == *\\\"* && \"$input\" == *\\'* ]]; then\n printf \"`%s`\\n\" \"$input\"\n elif [[ \"$input\" == *\\\"* ]]; then\n printf \"'%s'\\n\" \"$input\"\n else\n printf \"\\\"%s\\\"\\n\" \"$input\"\n fi\n else\n printf \"%s\\n\" \"$input\"\n fi\n ")); var escapeBashExpressionForDotEnv = function (value) { return value.transformWithCommand(escapeForDotEnvScript.name).toString(); };