зеркало из https://github.com/Azure/mysql.git
123 строки
6.5 KiB
JavaScript
123 строки
6.5 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
/**
|
|
* The basic format of a connection string includes a series of keyword/value pairs separated by semicolons.
|
|
* The equal sign (=) connects each keyword and its value. (Ex: Key1=Val1;Key2=Val2)
|
|
*
|
|
* Following rules are to be followed while passing special characters in values:
|
|
1. To include values that contain a semicolon, single-quote character, or double-quote character, the value must be enclosed in double quotation marks.
|
|
2. If the value contains both a semicolon and a double-quote character, the value can be enclosed in single quotation marks.
|
|
3. The single quotation mark is also useful if the value starts with a double-quote character. Conversely, the double quotation mark can be used if the value starts with a single quotation mark.
|
|
4. If the value contains both single-quote and double-quote characters, the quotation mark character used to enclose the value must be doubled every time it occurs within the value.
|
|
|
|
Regex used by the parser(connectionStringParserRegex) to parse the VALUE:
|
|
|
|
('[^']*(''[^']*)*') -> value enclosed with single quotes and has consecutive single quotes
|
|
|("[^"]*(""[^"]*)*") -> value enclosed with double quotes and has consecutive double quotes
|
|
|((?!['"])[^;]*)) -> value does not start with quotes does not contain any special character. Here we do a positive lookahead to ensure that the value doesn't start with quotes which should have been handled in previous cases
|
|
Regex used to validate the entire connection string:
|
|
|
|
A connection string is considered valid if it is a series of key/value pairs separated by semicolons. Each key/value pair must satisy the connectionStringParserRegex to ensure it is a valid key/value pair.
|
|
^[;\s]*{KeyValueRegex}(;[;\s]*{KeyValueRegex})*[;\s]*$
|
|
where KeyValueRegex = ([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))))
|
|
*/
|
|
const core = __importStar(require("@actions/core"));
|
|
const connectionStringParserRegex = /(?<key>[\w\s]+)=(?<val>('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))/g;
|
|
const connectionStringTester = /^[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*)))(;[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))))*[;\s]*$/;
|
|
class MySqlConnectionStringBuilder {
|
|
constructor(connectionString) {
|
|
this._connectionString = '';
|
|
this._connectionString = connectionString;
|
|
this._validateConnectionString();
|
|
this._parsedConnectionString = this._parseConnectionString();
|
|
}
|
|
get connectionString() {
|
|
return this._connectionString;
|
|
}
|
|
get userId() {
|
|
return this._parsedConnectionString.userId;
|
|
}
|
|
get password() {
|
|
return this._parsedConnectionString.password;
|
|
}
|
|
get server() {
|
|
return this._parsedConnectionString.server;
|
|
}
|
|
get database() {
|
|
return this._parsedConnectionString.database;
|
|
}
|
|
_validateConnectionString() {
|
|
if (!connectionStringTester.test(this._connectionString)) {
|
|
throw new Error('Invalid connection string. A valid connection string is a series of keyword/value pairs separated by semi-colons. If there are any special characters like quotes, semi-colons in the keyword value, enclose the value within quotes. Refer this link for more info on conneciton string https://aka.ms/sqlconnectionstring');
|
|
}
|
|
}
|
|
_parseConnectionString() {
|
|
let result = this._connectionString.matchAll(connectionStringParserRegex);
|
|
let parsedConnectionString = {};
|
|
for (let match of result) {
|
|
if (match.groups) {
|
|
let key = match.groups.key.trim();
|
|
let val = match.groups.val.trim();
|
|
/**
|
|
* If the first character of val is a single/double quote and there are two consecutive single/double quotes in between,
|
|
* convert the consecutive single/double quote characters into one single/double quote character respectively (Point no. 4 above)
|
|
*/
|
|
if (val[0] === "'") {
|
|
val = val.slice(1, -1);
|
|
val = val.replace(/''/g, "'");
|
|
}
|
|
else if (val[0] === '"') {
|
|
val = val.slice(1, -1);
|
|
val = val.replace(/""/g, '"');
|
|
}
|
|
switch (key.toLowerCase()) {
|
|
case 'user id':
|
|
case 'uid': {
|
|
parsedConnectionString.userId = val;
|
|
break;
|
|
}
|
|
case 'password':
|
|
case 'pwd': {
|
|
parsedConnectionString.password = val;
|
|
// masking the connection string password to prevent logging to console
|
|
core.setSecret(val);
|
|
break;
|
|
}
|
|
case 'database': {
|
|
parsedConnectionString.database = val;
|
|
break;
|
|
}
|
|
case 'server': {
|
|
parsedConnectionString.server = val;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!parsedConnectionString.server || !parsedConnectionString.userId || !parsedConnectionString.password) {
|
|
throw new Error(`Missing required keys in connection string. Please ensure that the keys 'Server', 'User Id', 'Password' are provided in the connection string.`);
|
|
}
|
|
return parsedConnectionString;
|
|
}
|
|
}
|
|
exports.default = MySqlConnectionStringBuilder;
|