mysql-memory-server 1.11.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,9 +15,9 @@ Download with your package manager of choice. The package name is `mysql-memory-
15
15
  #### Currently supported MySQL versions
16
16
 
17
17
  - ```mysql-memory-server``` can run MySQL versions 5.7.19 and newer (if the version is already installed on your system)
18
- - ```mysql-memory-server``` can download and run MySQL versions 5.7.19 - 5.7.44, 8.0.0 - 8.0.43, 8.1.0 - 8.4.6, and 9.0.1 - 9.4.0 (if the version is not already installed on your system - all version numbers are inclusive)
18
+ - ```mysql-memory-server``` can download and run MySQL versions (inclusive) 5.7.19 - 5.7.44, 8.0.0 - 8.0.43, 8.1.0 - 8.4.6, and 9.0.1 - 9.4.0 (if the version is not already installed on your system)
19
19
 
20
- Extra system requirements apply when ```mysql-memory-server``` is downloading MySQL instead of running a version of MySQL that is already installed on the system. To see the requirements and learn more about the supported versions for download, [read the doc](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.11.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md)
20
+ Extra system requirements apply when ```mysql-memory-server``` is downloading MySQL instead of running a version of MySQL that is already installed on the system. To see the requirements and learn more about the supported versions for download, [read the doc](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.12.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md)
21
21
 
22
22
  ## Example Usage - Application Code
23
23
 
@@ -78,7 +78,7 @@ npx mysql-memory-server@latest --version 8.4.x
78
78
  - `port: number`
79
79
  The port that the MySQL database is listening on
80
80
  - `xPort: number`
81
- The port that MySQLX is listening on
81
+ The port that MySQLX is listening on. If ```options.xEnabled``` is set to "OFF", this value will be -1.
82
82
  - `dbName: string`
83
83
  The database that was created on database initialization
84
84
  - `username: string`
@@ -86,9 +86,9 @@ The name of the user to use to login to the database
86
86
  - `socket: string`
87
87
  If on Windows, this is the name of the named pipe that MySQL is listening on. If not on Windows, this is the path to the socket that MySQL is listening on.
88
88
  - `xSocket: string`
89
- If on Windows, this is the name of the named pipe that the MySQL X Plugin is listening on. If not on Windows, this is the path that the MySQL X Plugin is listening on.
89
+ If on Windows, this is the name of the named pipe that the MySQL X Plugin is listening on. If not on Windows, this is the path that the MySQL X Plugin is listening on. If ```options.xEnabled``` is set to "OFF", this value will be an empty string.
90
90
  - `mysql: {version: string, versionIsInstalledOnSystem: boolean}`
91
- An object with two properties. ```version``` is the version of MySQL used to create the database. ```versionIsInstalledOnSystem``` will be true if the MySQL version used is already installed on the system and false if the version had to be downloaded from MySQL's CDN.
91
+ An object with three properties. ```version``` is the version of MySQL used to create the database. ```versionIsInstalledOnSystem``` will be true if the MySQL version used is already installed on the system and false if the version had to be downloaded from MySQL's CDN.
92
92
  - `stop: () => Promise<void>`
93
93
  The method to stop the database. The returned promise resolves when the database has successfully stopped.
94
94
 
@@ -102,11 +102,11 @@ Description: Version of MySQL to use for the database. Uses semver for getting t
102
102
 
103
103
  If left undefined:
104
104
  - If the system has MySQL installed, the system-installed version will be used. If the installed version is not supported by this package (currently <5.7.19), an error will be thrown unless `ignoreUnsupportedSystemVersion` is set to `true`.
105
- - If the system does not have MySQL installed, the latest version of MySQL that [this package supports downloading](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.11.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md) will be downloaded.
105
+ - If the system does not have MySQL installed, the latest version of MySQL that [this package supports downloading](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.12.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md) will be downloaded.
106
106
 
107
107
  If defined:
108
108
  - If the version is older than 5.7.19, an error will be thrown as this package does not currently support those versions of MySQL.
109
- - If the desired version of MySQL is already installed on the system, the installed version will be used. Otherwise the selected version will be downloaded as long as this package [supports downloading it](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.11.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md). If this package does not support downloading the selected version, or your system does not [meet the requirements](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.11.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md) for that version to be ran, an error will be thrown.
109
+ - If the desired version of MySQL is already installed on the system, the installed version will be used. Otherwise the selected version will be downloaded as long as this package [supports downloading it](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.12.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md). If this package does not support downloading the selected version, or your system does not [meet the requirements](https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/blob/v1.12.0/docs/SUPPORTED_MYSQL_DOWNLOADS.md) for that version to be ran, an error will be thrown.
110
110
 
111
111
  - `dbName: string`
112
112
 
@@ -189,3 +189,9 @@ The internal queries that are ran before the queries in ```initSQLString``` are
189
189
  Default: process.arch
190
190
 
191
191
  Description: The MySQL binary architecture to execute. MySQL does not offer server builds for Windows on ARM, so to get this package working on Windows on ARM, set the arch option to "x64" and Windows will emulate MySQL.
192
+
193
+ - `xEnabled: "OFF" | "FORCE"`
194
+
195
+ Default: "FORCE"
196
+
197
+ Description: This option follows the convention set out by the [MySQL Documentation](https://dev.mysql.com/doc/refman/en/plugin-loading.html). If set to "OFF", the MySQL X Plugin will not initialise. If set to "FORCE", the MySQL Server will either start up with the MySQL X Plugin guaranteed to have successfully initialised, or if initialisation fails, the server will fail to start up.
package/dist/src/cli.js CHANGED
File without changes
@@ -15,8 +15,8 @@ declare const internalOptions: {
15
15
  export declare function getInternalEnvVariable(envVar: keyof typeof internalOptions): string;
16
16
  export declare const OPTION_TYPE_CHECKS: OptionTypeChecks;
17
17
  export declare const MIN_SUPPORTED_MYSQL = "5.7.19";
18
- export declare const downloadsBaseURL = "https://cdn.mysql.com//Downloads/MySQL-";
19
- export declare const archiveBaseURL = "https://cdn.mysql.com/archives/mysql-";
18
+ export declare const MySQLCDNDownloadsBaseURL = "https://cdn.mysql.com//Downloads/MySQL-";
19
+ export declare const MySQLCDNArchivesBaseURL = "https://cdn.mysql.com/archives/mysql-";
20
20
  export declare const DOWNLOADABLE_MYSQL_VERSIONS: readonly ["5.7.19", "5.7.20", "5.7.21", "5.7.22", "5.7.23", "5.7.24", "5.7.25", "5.7.26", "5.7.27", "5.7.28", "5.7.29", "5.7.30", "5.7.31", "5.7.32", "5.7.33", "5.7.34", "5.7.35", "5.7.36", "5.7.37", "5.7.38", "5.7.39", "5.7.40", "5.7.41", "5.7.42", "5.7.43", "5.7.44", "8.0.0", "8.0.1", "8.0.2", "8.0.3", "8.0.4", "8.0.11", "8.0.12", "8.0.13", "8.0.14", "8.0.15", "8.0.16", "8.0.17", "8.0.18", "8.0.19", "8.0.20", "8.0.21", "8.0.22", "8.0.23", "8.0.24", "8.0.25", "8.0.26", "8.0.27", "8.0.28", "8.0.30", "8.0.31", "8.0.32", "8.0.33", "8.0.34", "8.0.35", "8.0.36", "8.0.37", "8.0.39", "8.0.40", "8.0.41", "8.0.42", "8.0.43", "8.1.0", "8.2.0", "8.3.0", "8.4.0", "8.4.2", "8.4.3", "8.4.4", "8.4.5", "8.4.6", "9.0.1", "9.1.0", "9.2.0", "9.3.0", "9.4.0"];
21
21
  export declare const MYSQL_ARCH_SUPPORT: {
22
22
  readonly darwin: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS = exports.MYSQL_LINUX_FILE_EXTENSIONS = exports.MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE_ARM64 = exports.MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE = exports.MYSQL_LINUX_GLIBC_VERSIONS = exports.MYSQL_MACOS_VERSIONS_IN_FILENAME = exports.RC_MYSQL_VERSIONS = exports.DMR_MYSQL_VERSIONS = exports.MYSQL_MIN_OS_SUPPORT = exports.MYSQL_ARCH_SUPPORT = exports.DOWNLOADABLE_MYSQL_VERSIONS = exports.archiveBaseURL = exports.downloadsBaseURL = exports.MIN_SUPPORTED_MYSQL = exports.OPTION_TYPE_CHECKS = exports.LOG_LEVELS = exports.DEFAULT_OPTIONS_KEYS = exports.DEFAULT_OPTIONS = void 0;
3
+ exports.MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS = exports.MYSQL_LINUX_FILE_EXTENSIONS = exports.MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE_ARM64 = exports.MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE = exports.MYSQL_LINUX_GLIBC_VERSIONS = exports.MYSQL_MACOS_VERSIONS_IN_FILENAME = exports.RC_MYSQL_VERSIONS = exports.DMR_MYSQL_VERSIONS = exports.MYSQL_MIN_OS_SUPPORT = exports.MYSQL_ARCH_SUPPORT = exports.DOWNLOADABLE_MYSQL_VERSIONS = exports.MySQLCDNArchivesBaseURL = exports.MySQLCDNDownloadsBaseURL = exports.MIN_SUPPORTED_MYSQL = exports.OPTION_TYPE_CHECKS = exports.LOG_LEVELS = exports.DEFAULT_OPTIONS_KEYS = exports.DEFAULT_OPTIONS = void 0;
4
4
  exports.getInternalEnvVariable = getInternalEnvVariable;
5
5
  const path_1 = require("path");
6
6
  const os_1 = require("os");
@@ -19,7 +19,8 @@ exports.DEFAULT_OPTIONS = {
19
19
  xPort: 0,
20
20
  downloadRetries: 10,
21
21
  initSQLString: '',
22
- arch: process.arch
22
+ arch: process.arch,
23
+ xEnabled: 'FORCE'
23
24
  };
24
25
  exports.DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys(exports.DEFAULT_OPTIONS));
25
26
  exports.LOG_LEVELS = {
@@ -38,6 +39,7 @@ function getInternalEnvVariable(envVar) {
38
39
  return process.env['mysqlmsn_internal_DO_NOT_USE_' + envVar] || internalOptions[envVar];
39
40
  }
40
41
  const allowedArches = ['x64', 'arm64'];
42
+ const pluginActivationStates = ['OFF', 'FORCE'];
41
43
  exports.OPTION_TYPE_CHECKS = {
42
44
  version: {
43
45
  check: (opt) => opt === undefined || typeof opt === 'string' && (0, semver_1.valid)((0, semver_1.coerce)(opt)) !== null,
@@ -108,11 +110,16 @@ exports.OPTION_TYPE_CHECKS = {
108
110
  check: (opt) => opt === undefined || allowedArches.includes(opt),
109
111
  errorMessage: `Option arch must be either of the following: ${allowedArches.join(', ')}`,
110
112
  definedType: 'string'
113
+ },
114
+ xEnabled: {
115
+ check: (opt) => opt === undefined || pluginActivationStates.includes(opt),
116
+ errorMessage: `xEnabled must be either undefined or one of the following: ${pluginActivationStates.join(', ')}`,
117
+ definedType: 'boolean'
111
118
  }
112
119
  };
113
120
  exports.MIN_SUPPORTED_MYSQL = '5.7.19';
114
- exports.downloadsBaseURL = 'https://cdn.mysql.com//Downloads/MySQL-';
115
- exports.archiveBaseURL = 'https://cdn.mysql.com/archives/mysql-';
121
+ exports.MySQLCDNDownloadsBaseURL = 'https://cdn.mysql.com//Downloads/MySQL-';
122
+ exports.MySQLCDNArchivesBaseURL = 'https://cdn.mysql.com/archives/mysql-';
116
123
  // Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues.
117
124
  exports.DOWNLOADABLE_MYSQL_VERSIONS = [
118
125
  '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44',
package/dist/src/index.js CHANGED
@@ -10,6 +10,7 @@ const semver_1 = require("semver");
10
10
  const Version_1 = __importDefault(require("./libraries/Version"));
11
11
  const Downloader_1 = require("./libraries/Downloader");
12
12
  const constants_1 = require("./constants");
13
+ const LinuxOSRelease_1 = __importDefault(require("./libraries/LinuxOSRelease"));
13
14
  async function createDB(opts) {
14
15
  const suppliedOpts = opts || {};
15
16
  const suppliedOptsKeys = Object.keys(suppliedOpts);
@@ -34,7 +35,7 @@ async function createDB(opts) {
34
35
  if (throwUnsupportedError) {
35
36
  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.`;
36
37
  }
37
- logger.log('Version currently installed:', version);
38
+ logger.log('Version currently installed:', version, 'Platform:', process.platform, 'etcOSRelease:', LinuxOSRelease_1.default);
38
39
  if (version === null || (options.version && !(0, semver_1.satisfies)(version.version, options.version)) || unsupportedMySQLIsInstalled) {
39
40
  let binaryInfo;
40
41
  let binaryFilepath;
@@ -47,7 +48,7 @@ async function createDB(opts) {
47
48
  throw `Failed to download binary. The error was: "${error}"`;
48
49
  }
49
50
  logger.log('Running downloaded binary');
50
- return await executor.startMySQL(options, { path: binaryFilepath, version: binaryInfo.version, installedOnSystem: false });
51
+ return await executor.startMySQL(options, { path: binaryFilepath, version: binaryInfo.version, installedOnSystem: false, xPluginSupported: binaryInfo.xPluginSupported });
51
52
  }
52
53
  else {
53
54
  logger.log(version);
@@ -56,6 +56,36 @@ function handleTarExtraction(filepath, extractedPath) {
56
56
  });
57
57
  });
58
58
  }
59
+ function getFileDownloadURLRedirect(url) {
60
+ const options = {
61
+ headers: {
62
+ 'accept': '*/*',
63
+ 'connection': 'keep-alive'
64
+ }
65
+ };
66
+ return new Promise((resolve, reject) => {
67
+ const request = https.get(url, options, response => {
68
+ const statusCode = response.statusCode;
69
+ const location = response.headers.location;
70
+ if (statusCode !== 302) {
71
+ request.destroy();
72
+ reject(`Received status code ${statusCode} while getting redirect URL for binary download. Used URL: ${url}`);
73
+ return;
74
+ }
75
+ if (typeof location === 'string' && location.length > 0) {
76
+ request.destroy();
77
+ resolve(location);
78
+ return;
79
+ }
80
+ request.destroy();
81
+ reject(`Received incorrect URL information. Expected a non-empty string. Received: ${JSON.stringify(location)}`);
82
+ });
83
+ request.on('error', (err) => {
84
+ request.destroy();
85
+ reject(err.message);
86
+ });
87
+ });
88
+ }
59
89
  function downloadFromCDN(url, downloadLocation, logger) {
60
90
  return new Promise(async (resolve, reject) => {
61
91
  if (fs.existsSync(downloadLocation)) {
@@ -139,7 +169,7 @@ function promisifiedZipExtraction(archiveLocation, extractedLocation) {
139
169
  });
140
170
  });
141
171
  }
142
- function extractBinary(url, archiveLocation, extractedLocation, logger) {
172
+ function extractBinary(url, archiveLocation, extractedLocation, binaryInfo, logger) {
143
173
  return new Promise(async (resolve, reject) => {
144
174
  if (fs.existsSync(extractedLocation)) {
145
175
  logger.warn('Removing item at extractedLocation:', extractedLocation, 'so the MySQL binary can be stored there. This is probably because a previous download/extraction failed.');
@@ -148,12 +178,18 @@ function extractBinary(url, archiveLocation, extractedLocation, logger) {
148
178
  const lastDashIndex = url.lastIndexOf('-');
149
179
  const fileExtension = url.slice(lastDashIndex).split('.').splice(1).join('.');
150
180
  await fsPromises.mkdir(extractedLocation, { recursive: true });
151
- const splitURL = url.split('/');
152
- const mySQLFolderName = splitURL[splitURL.length - 1];
153
- if (!mySQLFolderName) {
154
- return reject(`Folder name is undefined for url: ${url}`);
181
+ let folderName = '';
182
+ if (binaryInfo.hostedByOracle) {
183
+ const splitURL = url.split('/');
184
+ const mySQLFolderName = splitURL[splitURL.length - 1];
185
+ if (!mySQLFolderName) {
186
+ return reject(`Folder name is undefined for url: ${url}`);
187
+ }
188
+ folderName = mySQLFolderName.replace(`.${fileExtension}`, '');
189
+ }
190
+ else {
191
+ folderName = `mysql-${binaryInfo.version}`;
155
192
  }
156
- const folderName = mySQLFolderName.replace(`.${fileExtension}`, '');
157
193
  let extractionError = undefined;
158
194
  if (fileExtension === 'zip') {
159
195
  //Only Windows MySQL files use the .zip extension
@@ -255,13 +291,13 @@ function downloadBinary(binaryInfo, options, logger) {
255
291
  let downloadTries = 0;
256
292
  let useDownloadsURL = false;
257
293
  do {
294
+ const downloadURL = binaryInfo.hostedByOracle ? `${useDownloadsURL ? constants_1.MySQLCDNDownloadsBaseURL : constants_1.MySQLCDNArchivesBaseURL}${url}` : await getFileDownloadURLRedirect(url);
258
295
  try {
259
296
  downloadTries++;
260
- const downloadURL = useDownloadsURL ? url.replace(constants_1.archiveBaseURL, constants_1.downloadsBaseURL) : url;
261
297
  logger.log(`Starting download for MySQL version ${version} from ${downloadURL}.`);
262
298
  await downloadFromCDN(downloadURL, archivePath, logger);
263
299
  logger.log(`Finished downloading MySQL version ${version} from ${downloadURL}. Now starting binary extraction.`);
264
- await extractBinary(downloadURL, archivePath, extractedPath, logger);
300
+ await extractBinary(downloadURL, archivePath, extractedPath, binaryInfo, logger);
265
301
  logger.log(`Finished extraction for version ${version}`);
266
302
  break;
267
303
  }
@@ -276,12 +312,12 @@ function downloadBinary(binaryInfo, options, logger) {
276
312
  catch (e) {
277
313
  logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
278
314
  }
279
- if (e?.includes?.('status code 404')) {
280
- if (!useDownloadsURL) {
281
- //Retry with downloads URL
282
- downloadTries--;
315
+ // If we got a 404 error while downloading a binary from Oracle and have not retried with the Downloads URL yet
316
+ // then retry with the Downloads URL. Otherwise, reject.
317
+ if (e?.includes('status code 404')) {
318
+ if (binaryInfo.hostedByOracle && useDownloadsURL === false) {
283
319
  useDownloadsURL = true;
284
- logger.log(`Encountered error 404 when using archives URL for version ${version}. Now retrying with the downloads URL.`);
320
+ downloadTries--;
285
321
  continue;
286
322
  }
287
323
  else {
@@ -289,9 +325,11 @@ function downloadBinary(binaryInfo, options, logger) {
289
325
  await releaseFunction();
290
326
  }
291
327
  catch (e) {
292
- logger.error('An error occurred while releasing lock after receiving a 404 error on both downloads and archives URLs. The error was:', e);
328
+ logger.error('An error occurred while releasing lock after receiving a 404 error on download. The error was:', e);
329
+ }
330
+ finally {
331
+ return reject(`Binary download for MySQL version ${binaryInfo.version} returned status code 404 at URL ${downloadURL}. Aborting download.`);
293
332
  }
294
- return reject(`Both URLs for MySQL version ${binaryInfo.version} returned status code 404. Aborting download.`);
295
333
  }
296
334
  }
297
335
  if (downloadTries > options.downloadRetries) {
@@ -322,17 +360,17 @@ function downloadBinary(binaryInfo, options, logger) {
322
360
  let downloadTries = 0;
323
361
  let useDownloadsURL = false;
324
362
  do {
363
+ const downloadURL = binaryInfo.hostedByOracle ? `${useDownloadsURL ? constants_1.MySQLCDNDownloadsBaseURL : constants_1.MySQLCDNArchivesBaseURL}${url}` : await getFileDownloadURLRedirect(url);
325
364
  const uuid = (0, crypto_1.randomUUID)();
326
365
  const zipFilepath = `${dirpath}/${uuid}.${fileExtension}`;
327
366
  logger.log('Binary filepath:', zipFilepath);
328
367
  const extractedPath = `${dirpath}/${uuid}`;
329
368
  try {
330
369
  downloadTries++;
331
- const downloadURL = useDownloadsURL ? url.replace(constants_1.archiveBaseURL, constants_1.downloadsBaseURL) : url;
332
370
  logger.log(`Starting download for MySQL version ${version} from ${downloadURL}.`);
333
371
  await downloadFromCDN(downloadURL, zipFilepath, logger);
334
372
  logger.log(`Finished downloading MySQL version ${version} from ${downloadURL}. Now starting binary extraction.`);
335
- const binaryPath = await extractBinary(downloadURL, zipFilepath, extractedPath, logger);
373
+ const binaryPath = await extractBinary(downloadURL, zipFilepath, extractedPath, binaryInfo, logger);
336
374
  logger.log(`Finished extraction for version ${version}`);
337
375
  return resolve(binaryPath);
338
376
  }
@@ -347,16 +385,16 @@ function downloadBinary(binaryInfo, options, logger) {
347
385
  catch (e) {
348
386
  logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
349
387
  }
350
- if (e?.includes?.('status code 404')) {
351
- if (!useDownloadsURL) {
352
- //Retry with downloads URL
353
- downloadTries--;
388
+ // If we got a 404 error while downloading a binary from Oracle and have not retried with the Downloads URL yet
389
+ // then retry with the Downloads URL. Otherwise, reject.
390
+ if (e?.includes('status code 404')) {
391
+ if (binaryInfo.hostedByOracle && useDownloadsURL === false) {
354
392
  useDownloadsURL = true;
355
- logger.log(`Encountered error 404 when using archives URL for version ${version}. Now retrying with the downloads URL.`);
393
+ downloadTries--;
356
394
  continue;
357
395
  }
358
396
  else {
359
- return reject(`Both URLs for MySQL version ${binaryInfo.version} returned status code 404. Aborting download.`);
397
+ return reject(`Binary download for MySQL version ${binaryInfo.version} returned status code 404 at URL ${downloadURL}. Aborting download.`);
360
398
  }
361
399
  }
362
400
  if (downloadTries > options.downloadRetries) {
@@ -7,6 +7,7 @@ declare class Executor {
7
7
  removeExitHandler: () => void;
8
8
  version: string;
9
9
  versionInstalledOnSystem: boolean;
10
+ versionSupportsMySQLX: boolean;
10
11
  databasePath: string;
11
12
  killedFromPortIssue: boolean;
12
13
  constructor(logger: Logger);
@@ -37,9 +37,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
37
37
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
38
38
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
39
39
  };
40
- var __importDefault = (this && this.__importDefault) || function (mod) {
41
- return (mod && mod.__esModule) ? mod : { "default": mod };
42
- };
43
40
  var _Executor_instances, _Executor_executeFile, _Executor_killProcess, _Executor_returnBinaryPathToDelete, _Executor_startMySQLProcess, _Executor_setupDataDirectories;
44
41
  Object.defineProperty(exports, "__esModule", { value: true });
45
42
  const child_process_1 = require("child_process");
@@ -53,7 +50,7 @@ const FileLock_1 = require("./FileLock");
53
50
  const signal_exit_1 = require("signal-exit");
54
51
  const crypto_1 = require("crypto");
55
52
  const constants_1 = require("../constants");
56
- const LinuxOSRelease_1 = __importDefault(require("./LinuxOSRelease"));
53
+ const LinuxOSRelease_1 = __importStar(require("./LinuxOSRelease"));
57
54
  class Executor {
58
55
  constructor(logger) {
59
56
  _Executor_instances.add(this);
@@ -94,7 +91,7 @@ class Executor {
94
91
  return reject('Could not get MySQL version');
95
92
  }
96
93
  else {
97
- versions.push({ version: version.version, path, installedOnSystem: true });
94
+ versions.push({ version: version.version, path, installedOnSystem: true, xPluginSupported: (0, semver_1.gte)(version, '5.7.19') });
98
95
  }
99
96
  }
100
97
  if (preferredVersion) {
@@ -124,15 +121,22 @@ class Executor {
124
121
  reject('Could not get installed MySQL version');
125
122
  }
126
123
  else {
127
- resolve({ version: version.version, path: 'mysqld', installedOnSystem: true });
124
+ resolve({ version: version.version, path: 'mysqld', installedOnSystem: true, xPluginSupported: (0, semver_1.gte)(version, '5.7.19') });
128
125
  }
129
126
  }
130
127
  }
131
128
  });
132
129
  }
133
130
  async startMySQL(options, installedMySQLBinary) {
131
+ if (installedMySQLBinary.xPluginSupported === false && options.xEnabled === 'FORCE') {
132
+ if (LinuxOSRelease_1.isOnAlpineLinux) {
133
+ throw "options.xEnabled is set to 'FORCE'. You are running this package on Alpine Linux. The MySQL binaries for Alpine Linux do not support the MySQL X Plugin. If you don't want to use the MySQL X Plugin, please set options.xEnabled to 'OFF' and that will remove this error message. If you must have MySQL X enabled for each database creation, please use a different OS to run this package.";
134
+ }
135
+ throw "options.xEnabled is set to 'FORCE'. The version of MySQL you are using does not support MySQL X. If you don't want to use the MySQL X Plugin, please set options.xEnabled to 'OFF'. Otherwise, if MySQL X is required, please use a different version of MySQL that supports the X plugin.";
136
+ }
134
137
  this.version = installedMySQLBinary.version;
135
138
  this.versionInstalledOnSystem = installedMySQLBinary.installedOnSystem;
139
+ this.versionSupportsMySQLX = installedMySQLBinary.xPluginSupported;
136
140
  this.removeExitHandler = (0, signal_exit_1.onExit)(() => {
137
141
  if ((0, constants_1.getInternalEnvVariable)('cli') === 'true') {
138
142
  console.log('\nShutting down the ephemeral MySQL database and cleaning all related files...');
@@ -165,12 +169,9 @@ class Executor {
165
169
  do {
166
170
  await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_setupDataDirectories).call(this, options, installedMySQLBinary, datadir, true);
167
171
  this.logger.log('Setting up directories was successful');
168
- const port = options.port || (0, Port_1.GenerateRandomPort)();
169
- const mySQLXPort = options.xPort || (0, Port_1.GenerateRandomPort)();
170
- this.logger.log('Using port:', port, 'and MySQLX port:', mySQLXPort, 'on retry:', retries);
171
172
  try {
172
173
  this.logger.log('Starting MySQL process');
173
- const resolved = await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_startMySQLProcess).call(this, options, port, mySQLXPort, datadir, this.databasePath, installedMySQLBinary.path);
174
+ const resolved = await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_startMySQLProcess).call(this, options, datadir, this.databasePath, installedMySQLBinary.path);
174
175
  this.logger.log('Starting process was successful');
175
176
  return resolved;
176
177
  }
@@ -182,7 +183,7 @@ class Executor {
182
183
  }
183
184
  retries++;
184
185
  if (retries <= options.portRetries) {
185
- this.logger.warn(`One or both of these ports are already in use: ${port} or ${mySQLXPort}. Now retrying... ${retries}/${options.portRetries} possible retries.`);
186
+ this.logger.warn(`Tried a port that is already in use. Now retrying... ${retries}/${options.portRetries} possible retries.`);
186
187
  }
187
188
  else {
188
189
  throw `The port has been retried ${options.portRetries} times and a free port could not be found.\nEither try again, or if this is a common issue, increase options.portRetries.`;
@@ -221,21 +222,20 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
221
222
  return splitPath.join('/');
222
223
  }
223
224
  return null;
224
- }, _Executor_startMySQLProcess = function _Executor_startMySQLProcess(options, port, mySQLXPort, datadir, dbPath, binaryFilepath) {
225
+ }, _Executor_startMySQLProcess = function _Executor_startMySQLProcess(options, datadir, dbPath, binaryFilepath) {
225
226
  const errors = [];
226
227
  const logFile = `${dbPath}/log.log`;
227
228
  const errorLogFile = `${datadir}/errorlog.err`;
229
+ const port = options.port || (0, Port_1.GenerateRandomPort)();
230
+ const mySQLXPort = options.xPort || (0, Port_1.GenerateRandomPort)();
228
231
  return new Promise(async (resolve, reject) => {
229
232
  await fsPromises.rm(logFile, { force: true });
230
233
  const socket = os.platform() === 'win32' ? `MySQL-${(0, crypto_1.randomUUID)()}` : `${dbPath}/m.sock`;
231
234
  const xSocket = os.platform() === 'win32' ? `MySQLX-${(0, crypto_1.randomUUID)()}` : `${dbPath}/x.sock`;
232
235
  const mysqlArguments = [
233
236
  '--no-defaults',
234
- '--mysqlx=FORCE',
235
237
  `--port=${port}`,
236
238
  `--datadir=${datadir}`,
237
- `--mysqlx-port=${mySQLXPort}`,
238
- `--mysqlx-socket=${xSocket}`,
239
239
  `--socket=${socket}`,
240
240
  `--general-log-file=${logFile}`,
241
241
  '--general-log=1',
@@ -245,24 +245,31 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
245
245
  `--log-error=${errorLogFile}`,
246
246
  `--user=${os.userInfo().username}`
247
247
  ];
248
- //<8.0.11 does not have MySQL X turned on by default so we will be installing the X Plugin in this if statement.
249
- //MySQL 5.7.12 introduced the X plugin, but according to https://dev.mysql.com/doc/refman/5.7/en/document-store-setting-up.html, the database needs to be initialised with version 5.7.19.
250
- //If the MySQL version is >=5.7.19 & <8.0.11 then install the X Plugin
251
- if ((0, semver_1.lt)(this.version, '8.0.11') && (0, semver_1.gte)(this.version, '5.7.19')) {
252
- const pluginExtension = os.platform() === 'win32' ? 'dll' : 'so';
253
- let pluginPath;
254
- const firstPath = (0, path_1.resolve)(`${binaryFilepath}/../../lib/plugin`);
255
- const secondPath = '/usr/lib/mysql/plugin';
256
- if (fs.existsSync(`${firstPath}/mysqlx.${pluginExtension}`)) {
257
- pluginPath = firstPath;
258
- }
259
- else if (os.platform() === 'linux' && fs.existsSync(`${secondPath}/mysqlx.so`)) {
260
- pluginPath = secondPath;
261
- }
262
- else {
263
- throw 'Could not install MySQL X as the path to the plugin cannot be found.';
248
+ if (this.versionSupportsMySQLX) {
249
+ mysqlArguments.push(`--mysqlx=${options.xEnabled}`);
250
+ }
251
+ if (options.xEnabled !== 'OFF') {
252
+ mysqlArguments.push(`--mysqlx-port=${mySQLXPort}`);
253
+ mysqlArguments.push(`--mysqlx-socket=${xSocket}`);
254
+ //<8.0.11 does not have MySQL X turned on by default so we will be installing the X Plugin in this if statement.
255
+ //MySQL 5.7.12 introduced the X plugin, but according to https://dev.mysql.com/doc/refman/5.7/en/document-store-setting-up.html, the database needs to be initialised with version 5.7.19.
256
+ //If the MySQL version is >=5.7.19 & <8.0.11 then install the X Plugin
257
+ if ((0, semver_1.lt)(this.version, '8.0.11') && (0, semver_1.gte)(this.version, '5.7.19')) {
258
+ const pluginExtension = os.platform() === 'win32' ? 'dll' : 'so';
259
+ let pluginPath;
260
+ const firstPath = (0, path_1.resolve)(`${binaryFilepath}/../../lib/plugin`);
261
+ const secondPath = '/usr/lib/mysql/plugin';
262
+ if (fs.existsSync(`${firstPath}/mysqlx.${pluginExtension}`)) {
263
+ pluginPath = firstPath;
264
+ }
265
+ else if (os.platform() === 'linux' && fs.existsSync(`${secondPath}/mysqlx.so`)) {
266
+ pluginPath = secondPath;
267
+ }
268
+ else {
269
+ throw 'Could not install MySQL X as the path to the plugin cannot be found.';
270
+ }
271
+ mysqlArguments.splice(1, 0, `--plugin-dir=${pluginPath}`, `--early-plugin-load=mysqlx=mysqlx.${pluginExtension};`);
264
272
  }
265
- mysqlArguments.splice(1, 0, `--plugin-dir=${pluginPath}`, `--early-plugin-load=mysqlx=mysqlx.${pluginExtension};`);
266
273
  }
267
274
  const process = (0, child_process_1.spawn)(binaryFilepath, mysqlArguments, { signal: this.DBDestroySignal.signal, killSignal: 'SIGKILL' });
268
275
  //resolveFunction is the function that will be called to resolve the promise that stops the database.
@@ -270,6 +277,10 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
270
277
  //Once ran, resolveFunction will be called.
271
278
  let resolveFunction;
272
279
  process.on('close', async (code, signal) => {
280
+ // Prevent open file watches when MySQL has been exited
281
+ // The file watch is only stopped if MySQL starts successfully
282
+ // This unwatch will prevent the watch from watching when the process has stopped.
283
+ fs.unwatchFile(errorLogFile);
273
284
  if (signal) {
274
285
  this.logger.log('Exiting because of aborted signal.');
275
286
  return;
@@ -361,11 +372,11 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
361
372
  }
362
373
  return; //Promise rejection will be handled in the process.on('close') section because this.killedFromPortIssue is being set to true
363
374
  }
364
- resolve({
375
+ const result = {
365
376
  port,
366
- xPort: mySQLXPort,
377
+ xPort: options.xEnabled === 'FORCE' ? mySQLXPort : -1,
367
378
  socket,
368
- xSocket,
379
+ xSocket: options.xEnabled === 'FORCE' ? xSocket : '',
369
380
  dbName: options.dbName,
370
381
  username: options.username,
371
382
  mysql: {
@@ -382,7 +393,8 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
382
393
  }
383
394
  });
384
395
  }
385
- });
396
+ };
397
+ resolve(result);
386
398
  }
387
399
  }
388
400
  });
@@ -1,3 +1,4 @@
1
1
  import { LinuxEtcOSRelease } from '../../types';
2
- declare const _default: LinuxEtcOSRelease;
3
- export default _default;
2
+ declare const releaseDetails: LinuxEtcOSRelease;
3
+ export declare const isOnAlpineLinux: boolean;
4
+ export default releaseDetails;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isOnAlpineLinux = void 0;
6
7
  const fs_1 = __importDefault(require("fs"));
7
8
  const releaseDetails = {};
8
9
  if (process.platform === 'linux') {
@@ -15,4 +16,5 @@ if (process.platform === 'linux') {
15
16
  }
16
17
  }
17
18
  }
19
+ exports.isOnAlpineLinux = process.platform === 'linux' && releaseDetails?.ID === 'alpine';
18
20
  exports.default = releaseDetails;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GenerateRandomPort = GenerateRandomPort;
4
+ const crypto_1 = require("crypto");
4
5
  function GenerateRandomPort() {
5
- return Math.floor(Math.random() * (65535 - 1024) + 1025);
6
+ //Min is inclusive and max is exclusive. Inclusive range would be 1025 - 65535
7
+ return (0, crypto_1.randomInt)(1025, 65536);
6
8
  }
@@ -32,15 +32,12 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.default = getBinaryURL;
40
37
  const os = __importStar(require("os"));
41
38
  const semver_1 = require("semver");
42
39
  const constants_1 = require("../constants");
43
- const LinuxOSRelease_1 = __importDefault(require("./LinuxOSRelease"));
40
+ const LinuxOSRelease_1 = __importStar(require("./LinuxOSRelease"));
44
41
  function getBinaryURL(versionToGet = "x", currentArch) {
45
42
  let selectedVersions = constants_1.DOWNLOADABLE_MYSQL_VERSIONS.filter(version => (0, semver_1.satisfies)(version, versionToGet));
46
43
  if (selectedVersions.length === 0) {
@@ -85,16 +82,25 @@ function getBinaryURL(versionToGet = "x", currentArch) {
85
82
  const minVersion = minVersions[0];
86
83
  throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.`;
87
84
  }
88
- if (process.platform === 'linux' && LinuxOSRelease_1.default.NAME === 'Ubuntu' && LinuxOSRelease_1.default.VERSION_ID >= '24.04') {
89
- //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1".
90
- //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04.
91
- //If there is a suitable filepath for libaio1t64 to be copied into for MySQL < 8.0.4 then this check can be removed and these older MySQL versions can run on Ubuntu.
92
- //Pull requests are welcome for adding >= Ubuntu 24.04 support for MySQL < 8.0.4.
93
- //A way to get MySQL running on Ubuntu >= 24.04 is to symlink libaio1t64 to the location libaio would be. It is not suitable for this package to be doing that automatically, so instead this package has been copying libaio1t64 into the MySQL binary folder.
94
- selectedVersions = selectedVersions.filter(v => !(0, semver_1.lt)(v, '8.0.4'));
95
- }
96
- if (selectedVersions.length === 0) {
97
- throw `You are running a version of Ubuntu that is too modern to run any MySQL versions with this package that match the following version requirement: ${versionToGet}. Please choose a newer version of MySQL to use, or if you believe this is a bug please report this on GitHub.`;
85
+ if (process.platform === 'linux') {
86
+ if (LinuxOSRelease_1.default.NAME === 'Ubuntu' && LinuxOSRelease_1.default.VERSION_ID >= '24.04') {
87
+ //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1".
88
+ //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04.
89
+ //If there is a suitable filepath for libaio1t64 to be copied into for MySQL < 8.0.4 then this check can be removed and these older MySQL versions can run on Ubuntu.
90
+ //Pull requests are welcome for adding >= Ubuntu 24.04 support for MySQL < 8.0.4.
91
+ //A way to get MySQL running on Ubuntu >= 24.04 is to symlink libaio1t64 to the location libaio would be. It is not suitable for this package to be doing that automatically, so instead this package has been copying libaio1t64 into the MySQL binary folder.
92
+ selectedVersions = selectedVersions.filter(v => !(0, semver_1.lt)(v, '8.0.4'));
93
+ if (selectedVersions.length === 0) {
94
+ throw `You are running a version of Ubuntu that is too modern to run any MySQL versions with this package that match the following version requirement: ${versionToGet}. Please choose a newer version of MySQL to use, or if you believe this is a bug please report this on GitHub.`;
95
+ }
96
+ }
97
+ else if (LinuxOSRelease_1.isOnAlpineLinux) {
98
+ //https://github.com/Sebastian-Webster/mysql-server-musl-binaries only has support for v8.4.x and 9.x binaries
99
+ selectedVersions = selectedVersions.filter(v => (0, semver_1.satisfies)(v, '8.4.x') || (0, semver_1.satisfies)(v, '9.x'));
100
+ if (selectedVersions.length === 0) {
101
+ throw 'mysql-memory-server has detected you are running this package on Alpine Linux. The source for MySQL with musl libc only provides binaries for MySQL 8.4.x and 9.x and as such only those versions can be used with this package. Please use 8.4.x or 9.x.';
102
+ }
103
+ }
98
104
  }
99
105
  //Sorts versions in descending order
100
106
  selectedVersions.sort((a, b) => a < b ? 1 : -1);
@@ -102,6 +108,7 @@ function getBinaryURL(versionToGet = "x", currentArch) {
102
108
  const isRC = (0, semver_1.satisfies)(selectedVersion, constants_1.RC_MYSQL_VERSIONS);
103
109
  const isDMR = (0, semver_1.satisfies)(selectedVersion, constants_1.DMR_MYSQL_VERSIONS);
104
110
  let fileLocation = '';
111
+ let xPluginSupported = true;
105
112
  if (currentOS === 'win32') {
106
113
  fileLocation = `${(0, semver_1.major)(selectedVersion)}.${(0, semver_1.minor)(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip`;
107
114
  }
@@ -110,6 +117,10 @@ function getBinaryURL(versionToGet = "x", currentArch) {
110
117
  const macOSVersionNameKey = MySQLmacOSVersionNameKeys.find(range => (0, semver_1.satisfies)(selectedVersion, range));
111
118
  fileLocation = `${(0, semver_1.major)(selectedVersion)}.${(0, semver_1.minor)(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-${constants_1.MYSQL_MACOS_VERSIONS_IN_FILENAME[macOSVersionNameKey]}-${currentArch === 'x64' ? 'x86_64' : 'arm64'}.tar.gz`;
112
119
  }
120
+ else if (LinuxOSRelease_1.isOnAlpineLinux) {
121
+ fileLocation = `https://github.com/Sebastian-Webster/mysql-server-musl-binaries/releases/download/current/mysql-musl-${selectedVersion}-${currentArch === 'x64' ? 'x86_64' : 'arm64'}.tar.gz`;
122
+ xPluginSupported = false;
123
+ }
113
124
  else if (currentOS === 'linux') {
114
125
  const glibcObject = constants_1.MYSQL_LINUX_GLIBC_VERSIONS[currentArch];
115
126
  const glibcVersionKeys = Object.keys(glibcObject);
@@ -124,8 +135,13 @@ function getBinaryURL(versionToGet = "x", currentArch) {
124
135
  const fileExtension = constants_1.MYSQL_LINUX_FILE_EXTENSIONS[currentArch][fileExtensionKey];
125
136
  fileLocation = `${(0, semver_1.major)(selectedVersion)}.${(0, semver_1.minor)(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'aarch64'}${minimalInstallAvailable !== 'no' && (process.arch !== 'arm64' ? true : (0, semver_1.satisfies)(selectedVersion, constants_1.MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE_ARM64)) ? `-minimal${(0, semver_1.satisfies)(selectedVersion, constants_1.MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS) ? '-rebuild' : ''}` : ''}.tar.${fileExtension}`;
126
137
  }
138
+ else {
139
+ throw 'You are running this package on an unsupported OS. Please use either Windows, macOS, or a Linux-based OS.';
140
+ }
127
141
  return {
128
142
  version: selectedVersion,
129
- url: constants_1.archiveBaseURL + fileLocation
143
+ url: fileLocation,
144
+ hostedByOracle: !LinuxOSRelease_1.isOnAlpineLinux, // Only the Alpine Linux binaries are not hosted on the MySQL CDN.
145
+ xPluginSupported
130
146
  };
131
147
  }
@@ -1,5 +1,6 @@
1
1
  import { ExecFileException } from "child_process";
2
2
  export type LOG_LEVEL = 'LOG' | 'WARN' | 'ERROR';
3
+ export type PluginActivationState = 'OFF' | 'FORCE';
3
4
  export type ServerOptions = {
4
5
  version?: string | undefined;
5
6
  dbName?: string | undefined;
@@ -15,6 +16,7 @@ export type ServerOptions = {
15
16
  downloadRetries?: number | undefined;
16
17
  initSQLString?: string | undefined;
17
18
  arch?: "arm64" | "x64" | undefined;
19
+ xEnabled?: PluginActivationState | undefined;
18
20
  };
19
21
  export type InternalServerOptions = {
20
22
  version?: string | undefined;
@@ -31,6 +33,7 @@ export type InternalServerOptions = {
31
33
  downloadRetries: number;
32
34
  initSQLString: string;
33
35
  arch: string;
36
+ xEnabled: PluginActivationState;
34
37
  };
35
38
  export type ExecuteFileReturn = {
36
39
  error: ExecFileException | null;
@@ -54,10 +57,13 @@ export type DownloadedMySQLVersion = {
54
57
  version: string;
55
58
  path: string;
56
59
  installedOnSystem: boolean;
60
+ xPluginSupported: boolean;
57
61
  };
58
62
  export type BinaryInfo = {
59
63
  url: string;
60
64
  version: string;
65
+ hostedByOracle: boolean;
66
+ xPluginSupported: boolean;
61
67
  };
62
68
  export type OptionTypeChecks = {
63
69
  [key in keyof Required<ServerOptions>]: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql-memory-server",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Spin up an ephemeral MySQL database from your JavaScript code",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -17,8 +17,8 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "test": "jest --verbose --colors",
20
- "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --runTestsByPath tests/concurrency.test.ts",
21
- "os-compat:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --runTestsByPath tests/versions.test.ts"
20
+ "test:ci": "jest tests/ci --setupFilesAfterEnv ./ciSetup.js --verbose --colors",
21
+ "os-compat:ci": "jest tests/versions.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors"
22
22
  },
23
23
  "engines": {
24
24
  "node": ">=16.6.0",
@@ -31,12 +31,12 @@
31
31
  "@babel/preset-env": "^7.28.0",
32
32
  "@babel/preset-typescript": "^7.27.1",
33
33
  "@types/adm-zip": "^0.5.5",
34
- "@types/node": "^24.0.10",
34
+ "@types/node": "^24.1.0",
35
35
  "@types/semver": "^7.7.0",
36
- "babel-jest": "^30.0.4",
37
- "jest": "^30.0.4",
38
- "mysql2": "^3.14.1",
39
- "typescript": "^5.8.3"
36
+ "babel-jest": "^30.0.5",
37
+ "jest": "^30.0.5",
38
+ "mysql2": "^3.14.3",
39
+ "typescript": "^5.9.2"
40
40
  },
41
41
  "dependencies": {
42
42
  "adm-zip": "^0.5.16",