Skip to content

Commit 92918b3

Browse files
build - 1.7.0
1 parent 34401f2 commit 92918b3

File tree

15 files changed

+437
-119
lines changed

15 files changed

+437
-119
lines changed

dist/src/cli.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
export {};

dist/src/cli.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env node
2+
"use strict";
3+
Object.defineProperty(exports, "__esModule", { value: true });
4+
const index_1 = require("./index");
5+
const constants_1 = require("./constants");
6+
async function main() {
7+
const definedOptions = process.argv.filter((option) => option.startsWith('--'));
8+
const options = {
9+
_DO_NOT_USE_beforeSignalCleanupMessage: '\nShutting down the epehemeral MySQL database and cleaning all related files...',
10+
_DO_NOT_USE_afterSignalCleanupMessage: 'Shutdown and cleanup is complete.'
11+
};
12+
for (const opt of definedOptions) {
13+
const index = process.argv.indexOf(opt);
14+
const optionValue = process.argv[index + 1];
15+
if (optionValue === undefined) {
16+
throw `Option ${opt} must have a value.`;
17+
}
18+
const optionName = opt.slice(2);
19+
const optionType = constants_1.OPTION_TYPE_CHECKS[optionName].definedType;
20+
//Try to convert the options to their correct types.
21+
//We do not need to do any proper type validation here as the library will make sure everything is correct.
22+
//Like for example, if a string is passed to a number option, it'll be converted to NaN here, but the library
23+
//will throw an error for it not being an actual number.
24+
if (optionType === 'boolean') {
25+
if (optionValue === 'true') {
26+
options[optionName] = true;
27+
}
28+
else if (optionValue === 'false') {
29+
options[optionName] = false;
30+
}
31+
else {
32+
options[optionName] = optionValue;
33+
}
34+
}
35+
else if (optionType === 'number') {
36+
options[optionName] = parseInt(optionValue);
37+
}
38+
else {
39+
options[opt.slice(2)] = optionValue;
40+
}
41+
}
42+
console.log('Creating ephemeral MySQL database...');
43+
const db = await (0, index_1.createDB)(options);
44+
console.log(`A MySQL databases has been successfully created with the following parameters:\n\nUsername: ${db.username} \nDatabase Name: ${db.dbName} \nPort: ${db.port} \nX Plugin Port: ${db.xPort} \nSocket: ${db.socket} \nX Plugin Socket: ${db.xSocket}\n`);
45+
console.log(`If you want to use the MySQL CLI client to connect to the database, you can use either commands: \nmysql -u ${db.username} -P ${db.port} --protocol tcp \nOR\nmysql -u ${db.username} --socket ${db.socket}`);
46+
}
47+
main();

dist/src/constants.d.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
declare const CONSTANTS: {
2-
MIN_SUPPORTED_MYSQL: string;
1+
import { InternalServerOptions, OptionTypeChecks } from "../types";
2+
export declare const MIN_SUPPORTED_MYSQL = "8.0.20";
3+
export declare const DEFAULT_OPTIONS_GENERATOR: () => InternalServerOptions;
4+
export declare const DEFAULT_OPTIONS_KEYS: readonly string[];
5+
export declare const LOG_LEVELS: {
6+
readonly LOG: 0;
7+
readonly WARN: 1;
8+
readonly ERROR: 2;
39
};
4-
export default CONSTANTS;
10+
export declare const INTERNAL_OPTIONS: readonly ["_DO_NOT_USE_deleteDBAfterStopped", "_DO_NOT_USE_dbPath", "_DO_NOT_USE_binaryDirectoryPath", "_DO_NOT_USE_beforeSignalCleanup", "_DO_NOT_USE_afterSignalCleanup"];
11+
export declare const OPTION_TYPE_CHECKS: OptionTypeChecks;

dist/src/constants.js

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,129 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
3-
const CONSTANTS = {
4-
MIN_SUPPORTED_MYSQL: '8.0.20'
3+
exports.OPTION_TYPE_CHECKS = exports.INTERNAL_OPTIONS = exports.LOG_LEVELS = exports.DEFAULT_OPTIONS_KEYS = exports.DEFAULT_OPTIONS_GENERATOR = exports.MIN_SUPPORTED_MYSQL = void 0;
4+
const crypto_1 = require("crypto");
5+
const path_1 = require("path");
6+
const os_1 = require("os");
7+
const semver_1 = require("semver");
8+
exports.MIN_SUPPORTED_MYSQL = '8.0.20';
9+
const DEFAULT_OPTIONS_GENERATOR = () => ({
10+
version: undefined,
11+
dbName: 'dbdata',
12+
logLevel: 'ERROR',
13+
portRetries: 10,
14+
downloadBinaryOnce: true,
15+
lockRetries: 1000,
16+
lockRetryWait: 1000,
17+
username: 'root',
18+
ignoreUnsupportedSystemVersion: false,
19+
port: 0,
20+
xPort: 0,
21+
downloadRetries: 10,
22+
initSQLString: '',
23+
_DO_NOT_USE_deleteDBAfterStopped: true,
24+
//mysqlmsn = MySQL Memory Server Node.js
25+
_DO_NOT_USE_dbPath: (0, path_1.normalize)(`${(0, os_1.tmpdir)()}/mysqlmsn/dbs/${(0, crypto_1.randomUUID)().replace(/-/g, '')}`),
26+
_DO_NOT_USE_binaryDirectoryPath: `${(0, os_1.tmpdir)()}/mysqlmsn/binaries`,
27+
_DO_NOT_USE_beforeSignalCleanupMessage: '',
28+
_DO_NOT_USE_afterSignalCleanupMessage: ''
29+
});
30+
exports.DEFAULT_OPTIONS_GENERATOR = DEFAULT_OPTIONS_GENERATOR;
31+
exports.DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys((0, exports.DEFAULT_OPTIONS_GENERATOR)()));
32+
exports.LOG_LEVELS = {
33+
'LOG': 0,
34+
'WARN': 1,
35+
'ERROR': 2
36+
};
37+
exports.INTERNAL_OPTIONS = ['_DO_NOT_USE_deleteDBAfterStopped', '_DO_NOT_USE_dbPath', '_DO_NOT_USE_binaryDirectoryPath', '_DO_NOT_USE_beforeSignalCleanup', '_DO_NOT_USE_afterSignalCleanup'];
38+
exports.OPTION_TYPE_CHECKS = {
39+
version: {
40+
check: (opt) => opt === undefined || typeof opt === 'string' && (0, semver_1.valid)(opt) !== null,
41+
errorMessage: 'Option version must be either undefined or a valid semver string.',
42+
definedType: 'string'
43+
},
44+
dbName: {
45+
check: (opt) => opt === undefined || typeof opt === 'string' && opt.length <= 64,
46+
errorMessage: 'Option dbName must be either undefined or a string that is not longer than 64 characters.',
47+
definedType: 'string'
48+
},
49+
logLevel: {
50+
check: (opt) => opt === undefined || Object.keys(exports.LOG_LEVELS).includes(opt),
51+
errorMessage: 'Option logLevel must be either undefined or "LOG", "WARN", or "ERROR".',
52+
definedType: 'string'
53+
},
54+
portRetries: {
55+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0,
56+
errorMessage: 'Option portRetries must be either undefined, a positive number, or 0.',
57+
definedType: 'number'
58+
},
59+
downloadBinaryOnce: {
60+
check: (opt) => opt === undefined || typeof opt === 'boolean',
61+
errorMessage: 'Option downloadBinaryOnce must be either undefined or a boolean.',
62+
definedType: 'boolean'
63+
},
64+
lockRetries: {
65+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0,
66+
errorMessage: 'Option lockRetries must be either undefined, a positive number, or 0.',
67+
definedType: 'number'
68+
},
69+
lockRetryWait: {
70+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0,
71+
errorMessage: 'Option lockRetryWait must be either undefined, a positive number, or 0.',
72+
definedType: 'number'
73+
},
74+
username: {
75+
check: (opt) => opt === undefined || typeof opt === 'string' && opt.length <= 32,
76+
errorMessage: 'Option username must be either undefined or a string that is not longer than 32 characters.',
77+
definedType: 'string'
78+
},
79+
ignoreUnsupportedSystemVersion: {
80+
check: (opt) => opt === undefined || typeof opt === 'boolean',
81+
errorMessage: 'Option ignoreUnsupportedSystemVersion must be either undefined or a boolean.',
82+
definedType: 'boolean'
83+
},
84+
port: {
85+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0 && opt <= 65535,
86+
errorMessage: 'Option port must be either undefined or a number that is between 0 and 65535 inclusive.',
87+
definedType: 'number'
88+
},
89+
xPort: {
90+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0 && opt <= 65535,
91+
errorMessage: 'Option xPort must be either undefined or a number that is between 0 and 65535 inclusive.',
92+
definedType: 'number'
93+
},
94+
downloadRetries: {
95+
check: (opt) => opt === undefined || typeof opt === 'number' && opt >= 0,
96+
errorMessage: 'Option downloadRetries must be either undefined, a positive number, or 0.',
97+
definedType: 'number'
98+
},
99+
initSQLString: {
100+
check: (opt) => opt === undefined || typeof opt === 'string',
101+
errorMessage: 'Option initSQLString must be either undefined or a string.',
102+
definedType: 'string'
103+
},
104+
_DO_NOT_USE_deleteDBAfterStopped: {
105+
check: (opt) => opt === undefined || typeof opt === 'boolean',
106+
errorMessage: 'Option _DO_NOT_USE_deleteDBAfterStopped must be either undefined or a boolean.',
107+
definedType: 'boolean'
108+
},
109+
_DO_NOT_USE_dbPath: {
110+
check: (opt) => opt === undefined || typeof opt === 'string',
111+
errorMessage: 'Option _DO_NOT_USE_dbPath must be either undefined or a string.',
112+
definedType: 'string'
113+
},
114+
_DO_NOT_USE_binaryDirectoryPath: {
115+
check: (opt) => opt === undefined || typeof opt === 'string',
116+
errorMessage: 'Option _DO_NOT_USE_binaryDirectoryPath must be either undefined or a string.',
117+
definedType: 'string'
118+
},
119+
_DO_NOT_USE_beforeSignalCleanupMessage: {
120+
check: (opt) => opt === undefined || typeof opt === 'string',
121+
errorMessage: 'Option _DO_NOT_USE_beforeSignalCleanup must be either undefined or a string.',
122+
definedType: 'string'
123+
},
124+
_DO_NOT_USE_afterSignalCleanupMessage: {
125+
check: (opt) => opt === undefined || typeof opt === 'string',
126+
errorMessage: 'Option _DO_NOT_USE_afterSignalCleanup must be either undefined or a string.',
127+
definedType: 'string'
128+
}
5129
};
6-
exports.default = CONSTANTS;

dist/src/index.js

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
1515
}) : function(o, v) {
1616
o["default"] = v;
1717
});
18-
var __importStar = (this && this.__importStar) || function (mod) {
19-
if (mod && mod.__esModule) return mod;
20-
var result = {};
21-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22-
__setModuleDefault(result, mod);
23-
return result;
24-
};
18+
var __importStar = (this && this.__importStar) || (function () {
19+
var ownKeys = function(o) {
20+
ownKeys = Object.getOwnPropertyNames || function (o) {
21+
var ar = [];
22+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23+
return ar;
24+
};
25+
return ownKeys(o);
26+
};
27+
return function (mod) {
28+
if (mod && mod.__esModule) return mod;
29+
var result = {};
30+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31+
__setModuleDefault(result, mod);
32+
return result;
33+
};
34+
})();
2535
var __importDefault = (this && this.__importDefault) || function (mod) {
2636
return (mod && mod.__esModule) ? mod : { "default": mod };
2737
};
@@ -34,38 +44,37 @@ const semver_1 = require("semver");
3444
const Version_1 = __importDefault(require("./libraries/Version"));
3545
const versions_json_1 = __importDefault(require("./versions.json"));
3646
const Downloader_1 = require("./libraries/Downloader");
37-
const crypto_1 = require("crypto");
38-
const path_1 = require("path");
39-
const constants_1 = __importDefault(require("./constants"));
47+
const constants_1 = require("./constants");
4048
async function createDB(opts) {
41-
const defaultOptions = {
42-
dbName: 'dbdata',
43-
logLevel: 'ERROR',
44-
portRetries: 10,
45-
downloadBinaryOnce: true,
46-
lockRetries: 1000,
47-
lockRetryWait: 1000,
48-
username: 'root',
49-
deleteDBAfterStopped: true,
50-
//mysqlmsn = MySQL Memory Server Node.js
51-
dbPath: (0, path_1.normalize)(`${os.tmpdir()}/mysqlmsn/dbs/${(0, crypto_1.randomUUID)().replace(/-/g, '')}`),
52-
ignoreUnsupportedSystemVersion: false,
53-
port: 0,
54-
xPort: 0,
55-
binaryDirectoryPath: `${os.tmpdir()}/mysqlmsn/binaries`,
56-
downloadRetries: 10,
57-
initSQLString: ''
58-
};
59-
const options = { ...defaultOptions, ...opts };
49+
const suppliedOpts = opts || {};
50+
const suppliedOptsKeys = Object.keys(suppliedOpts);
51+
for (const opt of constants_1.INTERNAL_OPTIONS) {
52+
if (suppliedOptsKeys.includes(opt)) {
53+
console.warn(`[ mysql-memory-server - Options WARN ]: Creating MySQL database with option ${opt}. This is considered unstable and should not be used externally. Please consider removing this option.`);
54+
}
55+
}
56+
const options = (0, constants_1.DEFAULT_OPTIONS_GENERATOR)();
57+
for (const opt of suppliedOptsKeys) {
58+
if (!constants_1.DEFAULT_OPTIONS_KEYS.includes(opt)) {
59+
throw `Option ${opt} is not a valid option.`;
60+
}
61+
if (!constants_1.OPTION_TYPE_CHECKS[opt].check(suppliedOpts[opt])) {
62+
//Supplied option failed the check
63+
throw constants_1.OPTION_TYPE_CHECKS[opt].errorMessage;
64+
}
65+
if (suppliedOpts[opt] !== undefined) {
66+
options[opt] = suppliedOpts[opt];
67+
}
68+
}
6069
const logger = new Logger_1.default(options.logLevel);
6170
const executor = new Executor_1.default(logger);
6271
const version = await executor.getMySQLVersion(options.version);
63-
const unsupportedMySQLIsInstalled = version && (0, semver_1.lt)(version.version, constants_1.default.MIN_SUPPORTED_MYSQL);
72+
const unsupportedMySQLIsInstalled = version && (0, semver_1.lt)(version.version, constants_1.MIN_SUPPORTED_MYSQL);
6473
const throwUnsupportedError = unsupportedMySQLIsInstalled && !options.ignoreUnsupportedSystemVersion && !options.version;
6574
if (throwUnsupportedError) {
6675
throw `A version of MySQL is installed on your system that is not supported by this package. If you want to download a MySQL binary instead of getting this error, please set the option "ignoreUnsupportedSystemVersion" to true.`;
6776
}
68-
if (options.version && (0, semver_1.lt)(options.version, constants_1.default.MIN_SUPPORTED_MYSQL)) {
77+
if (options.version && (0, semver_1.lt)(options.version, constants_1.MIN_SUPPORTED_MYSQL)) {
6978
//The difference between the throw here and the throw above is this throw is because the selected "version" is not supported.
7079
//The throw above is because the system-installed MySQL is out of date and "ignoreUnsupportedSystemVersion" is not set to true.
7180
throw `The selected version of MySQL (${options.version}) is not currently supported by this package. Please choose a different version to use.`;

dist/src/libraries/Downloader.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
1515
}) : function(o, v) {
1616
o["default"] = v;
1717
});
18-
var __importStar = (this && this.__importStar) || function (mod) {
19-
if (mod && mod.__esModule) return mod;
20-
var result = {};
21-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22-
__setModuleDefault(result, mod);
23-
return result;
24-
};
18+
var __importStar = (this && this.__importStar) || (function () {
19+
var ownKeys = function(o) {
20+
ownKeys = Object.getOwnPropertyNames || function (o) {
21+
var ar = [];
22+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23+
return ar;
24+
};
25+
return ownKeys(o);
26+
};
27+
return function (mod) {
28+
if (mod && mod.__esModule) return mod;
29+
var result = {};
30+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31+
__setModuleDefault(result, mod);
32+
return result;
33+
};
34+
})();
2535
var __importDefault = (this && this.__importDefault) || function (mod) {
2636
return (mod && mod.__esModule) ? mod : { "default": mod };
2737
};
@@ -35,7 +45,6 @@ const adm_zip_1 = __importDefault(require("adm-zip"));
3545
const path_1 = require("path");
3646
const crypto_1 = require("crypto");
3747
const child_process_1 = require("child_process");
38-
const proper_lockfile_1 = require("proper-lockfile");
3948
const FileLock_1 = require("./FileLock");
4049
function getZipData(entry) {
4150
return new Promise((resolve, reject) => {
@@ -199,7 +208,7 @@ function extractBinary(url, archiveLocation, extractedLocation, logger) {
199208
function downloadBinary(binaryInfo, options, logger) {
200209
return new Promise(async (resolve, reject) => {
201210
const { url, version } = binaryInfo;
202-
const dirpath = options.binaryDirectoryPath;
211+
const dirpath = options._DO_NOT_USE_binaryDirectoryPath;
203212
logger.log('Binary path:', dirpath);
204213
await fsPromises.mkdir(dirpath, { recursive: true });
205214
const lastDashIndex = url.lastIndexOf('-');
@@ -215,11 +224,11 @@ function downloadBinary(binaryInfo, options, logger) {
215224
let releaseFunction;
216225
while (true) {
217226
try {
218-
releaseFunction = (0, proper_lockfile_1.lockSync)(extractedPath, { realpath: false });
227+
releaseFunction = await (0, FileLock_1.lockFile)(extractedPath);
219228
break;
220229
}
221230
catch (e) {
222-
if (e.code === 'ELOCKED') {
231+
if (e === 'LOCKED') {
223232
logger.log('Waiting for lock for MySQL version', version);
224233
await (0, FileLock_1.waitForLock)(extractedPath, options);
225234
logger.log('Lock is gone for version', version);
@@ -253,10 +262,10 @@ function downloadBinary(binaryInfo, options, logger) {
253262
catch (e) {
254263
logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
255264
}
256-
if (downloadTries >= options.downloadRetries) {
265+
if (downloadTries > options.downloadRetries) {
257266
//Only reject if we have met the downloadRetries limit
258267
try {
259-
releaseFunction();
268+
await releaseFunction();
260269
}
261270
catch (e) {
262271
logger.error('An error occurred while releasing lock after downloadRetries exhaustion. The error was:', e);
@@ -268,7 +277,7 @@ function downloadBinary(binaryInfo, options, logger) {
268277
console.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e);
269278
}
270279
}
271-
} while (downloadTries < options.downloadRetries);
280+
} while (downloadTries <= options.downloadRetries);
272281
try {
273282
releaseFunction();
274283
}
@@ -301,15 +310,15 @@ function downloadBinary(binaryInfo, options, logger) {
301310
catch (e) {
302311
logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
303312
}
304-
if (downloadTries >= options.downloadRetries) {
313+
if (downloadTries > options.downloadRetries) {
305314
//Only reject if we have met the downloadRetries limit
306315
return reject(e);
307316
}
308317
else {
309318
console.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e);
310319
}
311320
}
312-
} while (downloadTries < options.downloadRetries);
321+
} while (downloadTries <= options.downloadRetries);
313322
}
314323
});
315324
}

0 commit comments

Comments
 (0)