@catladder/pipeline
Version:
Panter workflow for cloud CI/CD and DevOps
127 lines (126 loc) • 5.95 kB
JavaScript
;
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();
};