mysql-memory-server 1.4.3 → 1.6.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
@@ -1,8 +1,8 @@
1
1
  # MySQL Memory Server
2
2
 
3
- This package allows you to create ephemeral MySQL databases inside of Node.js, great for testing. When creating a new database, if the version selected is not installed on the system, the binary is downloaded from MySQL's CDN (cdn.mysql.com)
3
+ This package allows you to create ephemeral MySQL databases from JavaScript and/or TypeScript code, great for testing. When creating a new database, if the version selected is not installed on the system, the binary is downloaded from MySQL's CDN (cdn.mysql.com)
4
4
 
5
- You can run multiple MySQL databases with this package at the same time. Each database will use a random free port. The databases will automatically shutdown when the Node.js process exits. A `stop()` method is also provided to stop each database instance.
5
+ You can run multiple MySQL databases with this package at the same time. Each database will use a random free port. The databases will automatically shutdown when the JS runtime process exits. A `stop()` method is also provided to stop each database instance.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,7 +10,7 @@ Download with your package manager of choice. The package name is `mysql-memory-
10
10
 
11
11
  #### Requirements
12
12
 
13
- - Node.js 16.6.0 and newer
13
+ - Node.js >=16.6.0 or Bun >= 1.0.0
14
14
  - macOS 13+, Windows, or Linux (This package is only tested on Ubuntu 20.04, 22.04, 24.04, and Fedora 40. Other Linux distributions may or may not work at this time.)
15
15
 
16
16
  #### Requirements for downloaded MySQL versions
@@ -28,10 +28,12 @@ Requirements for Linux:
28
28
  #### Currently supported MySQL versions
29
29
 
30
30
  - If using the system installed MySQL server: 8.0.20 and newer
31
- - If not using the system installed MySQL server: 8.0.39, 8.1.0, 8.2.0, 8.3.0, 8.4.2, 9.0.1
31
+ - If not using the system installed MySQL server: 8.0.39, 8.0.40, 8.1.0, 8.2.0, 8.3.0, 8.4.2, 8.4.3, 9.0.1, 9.1.0
32
32
 
33
33
  ## Usage
34
34
 
35
+ This package supports both ESM and CJS so you can use import or require.
36
+
35
37
  ```javascript
36
38
  import { createDB } from 'mysql-memory-server';
37
39
  import sql from 'mysql2/promise'
@@ -186,6 +188,24 @@ Default: false
186
188
 
187
189
  Description: This option only applies if the system-installed MySQL version is lower than the oldest supported MySQL version for this package (8.0.20) and the `version` option is not defined. If set to `true`, this package will use the latest version of MySQL instead of the system-installed version. If `false`, the package will throw an error.
188
190
 
191
+ - `downloadRetries: number`
192
+
193
+ Required: No
194
+
195
+ Default: 3
196
+
197
+ Description: The number of times to try to download a MySQL binary before giving up and rejecting the `createDB()` promise.
198
+
199
+ - `initSQLString: string`
200
+
201
+ Required: No
202
+
203
+ Default: ""
204
+
205
+ Description: A string with MySQL queries to run before the database starts to accept connections. This option can be used for things like initialising tables without having to first connect to the database to do that.The queries in the string get executed after ```mysql-memory-server```'s queries run. Uses the ```--init-file``` MySQL server option under the hood. Learn more at the [--init-file MySQL Documentation](https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html#sysvar_init_file)
206
+
207
+ The internal queries that are ran before the queries in ```initSQLString``` are renaming the user from ```root``` to the username specified in the ```username``` option if it's set, and creating a database with the name from the ```dbName``` option.
208
+
189
209
  ***
190
210
  ### :warning: Internal Options :warning:
191
211
 
package/dist/src/index.js CHANGED
@@ -52,7 +52,9 @@ async function createDB(opts) {
52
52
  ignoreUnsupportedSystemVersion: false,
53
53
  port: 0,
54
54
  xPort: 0,
55
- binaryDirectoryPath: `${os.tmpdir()}/mysqlmsn/binaries`
55
+ binaryDirectoryPath: `${os.tmpdir()}/mysqlmsn/binaries`,
56
+ downloadRetries: 10,
57
+ initSQLString: ''
56
58
  };
57
59
  const options = { ...defaultOptions, ...opts };
58
60
  const logger = new Logger_1.default(options.logLevel);
@@ -75,12 +75,37 @@ function downloadVersions() {
75
75
  });
76
76
  }
77
77
  function downloadFromCDN(url, downloadLocation, logger) {
78
- return new Promise((resolve, reject) => {
78
+ return new Promise(async (resolve, reject) => {
79
+ if (fs.existsSync(downloadLocation)) {
80
+ logger.warn('Removing item at downloadLocation:', downloadLocation, 'so the MySQL binary archive can be stored there. This is probably because a previous download/extraction failed.');
81
+ await fsPromises.rm(downloadLocation, { recursive: true, force: true });
82
+ }
79
83
  const fileStream = fs.createWriteStream(downloadLocation);
80
84
  let error;
81
85
  fileStream.on('open', () => {
82
86
  const request = https.get(url, (response) => {
83
- response.pipe(fileStream);
87
+ if (response.statusCode !== 200) {
88
+ fileStream.close((err) => {
89
+ if (err) {
90
+ logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err);
91
+ }
92
+ fs.unlink(downloadLocation, (unlinkErr) => {
93
+ if (unlinkErr) {
94
+ logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', err);
95
+ }
96
+ logger.error('Received status code:', response.statusCode, 'while downloading MySQL binary.');
97
+ reject(`Received status code ${response.statusCode} while downloading MySQL binary.`);
98
+ });
99
+ });
100
+ }
101
+ else {
102
+ response.pipe(fileStream);
103
+ fileStream.on('finish', () => {
104
+ if (!error) {
105
+ resolve();
106
+ }
107
+ });
108
+ }
84
109
  });
85
110
  request.on('error', (err) => {
86
111
  error = err;
@@ -95,11 +120,6 @@ function downloadFromCDN(url, downloadLocation, logger) {
95
120
  });
96
121
  });
97
122
  });
98
- fileStream.on('finish', () => {
99
- if (!error) {
100
- resolve();
101
- }
102
- });
103
123
  fileStream.on('error', (err) => {
104
124
  error = err;
105
125
  logger.error(err);
@@ -116,6 +136,10 @@ function downloadFromCDN(url, downloadLocation, logger) {
116
136
  }
117
137
  function extractBinary(url, archiveLocation, extractedLocation, logger) {
118
138
  return new Promise(async (resolve, reject) => {
139
+ if (fs.existsSync(extractedLocation)) {
140
+ logger.warn('Removing item at extractedLocation:', extractedLocation, 'so the MySQL binary can be stored there. This is probably because a previous download/extraction failed.');
141
+ await fsPromises.rm(extractedLocation, { recursive: true, force: true });
142
+ }
119
143
  const lastDashIndex = url.lastIndexOf('-');
120
144
  const fileExtension = url.slice(lastDashIndex).split('.').splice(1).join('.');
121
145
  await fsPromises.mkdir(extractedLocation, { recursive: true });
@@ -167,7 +191,8 @@ function extractBinary(url, archiveLocation, extractedLocation, logger) {
167
191
  resolve(`${extractedLocation}/mysql/bin/mysqld`);
168
192
  }
169
193
  }).catch(error => {
170
- reject(`An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was: ${error}`);
194
+ logger.error(`An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was: ${error}`);
195
+ reject(error);
171
196
  });
172
197
  });
173
198
  }
@@ -190,8 +215,7 @@ function downloadBinary(binaryInfo, options, logger) {
190
215
  let releaseFunction;
191
216
  while (true) {
192
217
  try {
193
- await fsPromises.mkdir(extractedPath, { recursive: true });
194
- releaseFunction = (0, proper_lockfile_1.lockSync)(extractedPath);
218
+ releaseFunction = (0, proper_lockfile_1.lockSync)(extractedPath, { realpath: false });
195
219
  break;
196
220
  }
197
221
  catch (e) {
@@ -210,54 +234,82 @@ function downloadBinary(binaryInfo, options, logger) {
210
234
  }
211
235
  }
212
236
  //The code below only runs if the lock has been acquired by us
213
- try {
214
- await downloadFromCDN(url, archivePath, logger);
215
- await extractBinary(url, archivePath, extractedPath, logger);
216
- }
217
- catch (e) {
237
+ let downloadTries = 0;
238
+ do {
218
239
  try {
219
- await Promise.all([
220
- fsPromises.rm(extractedPath, { force: true, recursive: true }),
221
- fsPromises.rm(archivePath, { force: true, recursive: true })
222
- ]);
240
+ downloadTries++;
241
+ await downloadFromCDN(url, archivePath, logger);
242
+ await extractBinary(url, archivePath, extractedPath, logger);
243
+ break;
223
244
  }
224
245
  catch (e) {
225
- logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
226
- }
227
- finally {
246
+ //Delete generated files since either download or extraction failed
228
247
  try {
229
- releaseFunction();
248
+ await Promise.all([
249
+ fsPromises.rm(extractedPath, { force: true, recursive: true }),
250
+ fsPromises.rm(archivePath, { force: true, recursive: true })
251
+ ]);
230
252
  }
231
253
  catch (e) {
232
- logger.error('An error occurred while unlocking path:', e);
254
+ logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
255
+ }
256
+ if (downloadTries >= options.downloadRetries) {
257
+ //Only reject if we have met the downloadRetries limit
258
+ try {
259
+ releaseFunction();
260
+ }
261
+ catch (e) {
262
+ logger.error('An error occurred while releasing lock after downloadRetries exhaustion. The error was:', e);
263
+ }
264
+ logger.error('downloadRetries have been exceeded. Aborting download.');
265
+ return reject(e);
266
+ }
267
+ else {
268
+ console.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e);
233
269
  }
234
- return reject(e);
235
270
  }
236
- }
271
+ } while (downloadTries < options.downloadRetries);
237
272
  try {
238
273
  releaseFunction();
239
274
  }
240
275
  catch (e) {
241
- return reject(e);
276
+ logger.error('An error occurred while releasing lock after successful binary download. The error was:', e);
242
277
  }
243
278
  return resolve(binaryPath);
244
279
  }
245
- const uuid = (0, crypto_1.randomUUID)();
246
- const zipFilepath = `${dirpath}/${uuid}.${fileExtension}`;
247
- logger.log('Binary filepath:', zipFilepath);
248
- const extractedPath = `${dirpath}/${uuid}`;
249
- try {
250
- await downloadFromCDN(url, zipFilepath, logger);
251
- }
252
- catch (e) {
253
- reject(e);
254
- }
255
- try {
256
- const binaryPath = await extractBinary(url, zipFilepath, extractedPath, logger);
257
- resolve(binaryPath);
258
- }
259
- catch (e) {
260
- reject(e);
280
+ else {
281
+ let downloadTries = 0;
282
+ do {
283
+ const uuid = (0, crypto_1.randomUUID)();
284
+ const zipFilepath = `${dirpath}/${uuid}.${fileExtension}`;
285
+ logger.log('Binary filepath:', zipFilepath);
286
+ const extractedPath = `${dirpath}/${uuid}`;
287
+ try {
288
+ downloadTries++;
289
+ await downloadFromCDN(url, zipFilepath, logger);
290
+ const binaryPath = await extractBinary(url, zipFilepath, extractedPath, logger);
291
+ return resolve(binaryPath);
292
+ }
293
+ catch (e) {
294
+ //Delete generated files since either download or extraction failed
295
+ try {
296
+ await Promise.all([
297
+ fsPromises.rm(extractedPath, { force: true, recursive: true }),
298
+ fsPromises.rm(zipFilepath, { force: true, recursive: true })
299
+ ]);
300
+ }
301
+ catch (e) {
302
+ logger.error('An error occurred while deleting extractedPath and/or archivePath:', e);
303
+ }
304
+ if (downloadTries >= options.downloadRetries) {
305
+ //Only reject if we have met the downloadRetries limit
306
+ return reject(e);
307
+ }
308
+ else {
309
+ console.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e);
310
+ }
311
+ }
312
+ } while (downloadTries < options.downloadRetries);
261
313
  }
262
314
  });
263
315
  }
@@ -4,7 +4,6 @@ declare class Executor {
4
4
  #private;
5
5
  logger: Logger;
6
6
  constructor(logger: Logger);
7
- deleteDatabaseDirectory(path: string): Promise<void>;
8
7
  getMySQLVersion(preferredVersion?: string): Promise<InstalledMySQLVersion | null>;
9
8
  startMySQL(options: InternalServerOptions, binaryFilepath: string): Promise<MySQLDB>;
10
9
  }
@@ -30,7 +30,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
30
30
  var __importDefault = (this && this.__importDefault) || function (mod) {
31
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
32
  };
33
- var _Executor_instances, _Executor_executeFile, _Executor_killProcess, _Executor_startMySQLProcess, _Executor_setupDataDirectories;
33
+ var _Executor_instances, _Executor_executeFile, _Executor_killProcess, _Executor_deleteDatabaseDirectory, _Executor_startMySQLProcess, _Executor_setupDataDirectories;
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
35
  const child_process_1 = require("child_process");
36
36
  const semver_1 = require("semver");
@@ -47,29 +47,6 @@ class Executor {
47
47
  _Executor_instances.add(this);
48
48
  this.logger = logger;
49
49
  }
50
- async deleteDatabaseDirectory(path) {
51
- let retries = 0;
52
- //Maximum wait of 10 seconds | 500ms * 20 retries = 10,000ms = 10 seconds
53
- const waitTime = 500;
54
- const maxRetries = 20;
55
- //Since the database processes are killed instantly (SIGKILL) sometimes the database file handles may still be open
56
- //This would cause an EBUSY error. Retrying the deletions for 10 seconds should give the OS enough time to close
57
- //the file handles.
58
- while (retries <= maxRetries) {
59
- try {
60
- await fsPromises.rm(path, { recursive: true, force: true });
61
- return;
62
- }
63
- catch (e) {
64
- if (retries === maxRetries) {
65
- throw e;
66
- }
67
- await new Promise(resolve => setTimeout(resolve, waitTime));
68
- retries++;
69
- this.logger.log('DB data directory deletion failed. Now on retry', retries);
70
- }
71
- }
72
- }
73
50
  getMySQLVersion(preferredVersion) {
74
51
  return new Promise(async (resolve, reject) => {
75
52
  if (process.platform === 'win32') {
@@ -182,6 +159,28 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
182
159
  killed = process.kill();
183
160
  }
184
161
  return killed;
162
+ }, _Executor_deleteDatabaseDirectory = async function _Executor_deleteDatabaseDirectory(path) {
163
+ let retries = 0;
164
+ //Maximum wait of 10 seconds | 500ms * 20 retries = 10,000ms = 10 seconds
165
+ const waitTime = 500;
166
+ const maxRetries = 20;
167
+ //Since the database processes are killed instantly (SIGKILL) sometimes the database file handles may still be open
168
+ //This would cause an EBUSY error. Retrying the deletions for 10 seconds should give the OS enough time to close
169
+ //the file handles.
170
+ while (retries <= maxRetries) {
171
+ try {
172
+ await fsPromises.rm(path, { recursive: true, force: true });
173
+ return;
174
+ }
175
+ catch (e) {
176
+ if (retries === maxRetries) {
177
+ throw e;
178
+ }
179
+ await new Promise(resolve => setTimeout(resolve, waitTime));
180
+ retries++;
181
+ this.logger.log('DB data directory deletion failed. Now on retry', retries);
182
+ }
183
+ }
185
184
  }, _Executor_startMySQLProcess = function _Executor_startMySQLProcess(options, port, mySQLXPort, datadir, dbPath, binaryFilepath) {
186
185
  const errors = [];
187
186
  const logFile = `${dbPath}/log.log`;
@@ -207,7 +206,7 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
207
206
  if (portIssue || xPortIssue) {
208
207
  this.logger.log('Error log when exiting for port in use error:', errorLog);
209
208
  try {
210
- await this.deleteDatabaseDirectory(options.dbPath);
209
+ await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_deleteDatabaseDirectory).call(this, options.dbPath);
211
210
  }
212
211
  catch (e) {
213
212
  this.logger.error(e);
@@ -217,7 +216,7 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
217
216
  }
218
217
  try {
219
218
  if (options.deleteDBAfterStopped) {
220
- await this.deleteDatabaseDirectory(dbPath);
219
+ await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_deleteDatabaseDirectory).call(this, dbPath);
221
220
  }
222
221
  }
223
222
  catch (e) {
@@ -407,7 +406,7 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
407
406
  }
408
407
  //Retry setting up directory now that libaio has been copied
409
408
  this.logger.log('Retrying directory setup');
410
- await this.deleteDatabaseDirectory(datadir);
409
+ await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_deleteDatabaseDirectory).call(this, datadir);
411
410
  await __classPrivateFieldGet(this, _Executor_instances, "m", _Executor_setupDataDirectories).call(this, options, binaryFilepath, datadir, false);
412
411
  return;
413
412
  }
@@ -424,6 +423,9 @@ _Executor_instances = new WeakSet(), _Executor_executeFile = function _Executor_
424
423
  if (options.username !== 'root') {
425
424
  initText += `\nRENAME USER 'root'@'localhost' TO '${options.username}'@'localhost';`;
426
425
  }
426
+ if (options.initSQLString.length > 0) {
427
+ initText += `\n${options.initSQLString}`;
428
+ }
427
429
  this.logger.log('Writing init file');
428
430
  await fsPromises.writeFile(`${options.dbPath}/init.sql`, initText, { encoding: 'utf8' });
429
431
  this.logger.log('Finished writing init file');
@@ -1,4 +1,109 @@
1
1
  [
2
+ {
3
+ "version": "9.1.0",
4
+ "arch": "arm64",
5
+ "os": "darwin",
6
+ "osKernelVersionsSupported": ">=22",
7
+ "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-macos14-arm64.tar.gz"
8
+ },
9
+ {
10
+ "version": "9.1.0",
11
+ "arch": "x64",
12
+ "os": "darwin",
13
+ "osKernelVersionsSupported": ">=22",
14
+ "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-macos14-x86_64.tar.gz"
15
+ },
16
+ {
17
+ "version": "9.1.0",
18
+ "arch": "x64",
19
+ "os": "linux",
20
+ "osKernelVersionsSupported": "*",
21
+ "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-linux-glibc2.17-x86_64-minimal.tar.xz"
22
+ },
23
+ {
24
+ "version": "9.1.0",
25
+ "arch": "arm64",
26
+ "os": "linux",
27
+ "osKernelVersionsSupported": "*",
28
+ "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-linux-glibc2.17-aarch64-minimal.tar.xz"
29
+ },
30
+ {
31
+ "version": "9.1.0",
32
+ "arch": "x64",
33
+ "os": "win32",
34
+ "osKernelVersionsSupported": "*",
35
+ "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-winx64.zip"
36
+ },
37
+ {
38
+ "version": "8.4.3",
39
+ "arch": "arm64",
40
+ "os": "darwin",
41
+ "osKernelVersionsSupported": ">=22",
42
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-macos14-arm64.tar.gz"
43
+ },
44
+ {
45
+ "version": "8.4.3",
46
+ "arch": "x64",
47
+ "os": "darwin",
48
+ "osKernelVersionsSupported": ">=22",
49
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-macos14-x86_64.tar.gz"
50
+ },
51
+ {
52
+ "version": "8.4.3",
53
+ "arch": "x64",
54
+ "os": "linux",
55
+ "osKernelVersionsSupported": "*",
56
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-x86_64-minimal.tar.xz"
57
+ },
58
+ {
59
+ "version": "8.4.3",
60
+ "arch": "arm64",
61
+ "os": "linux",
62
+ "osKernelVersionsSupported": "*",
63
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-aarch64-minimal.tar.xz"
64
+ },
65
+ {
66
+ "version": "8.4.3",
67
+ "arch": "x64",
68
+ "os": "win32",
69
+ "osKernelVersionsSupported": "*",
70
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-winx64.zip"
71
+ },
72
+ {
73
+ "version": "8.0.40",
74
+ "arch": "arm64",
75
+ "os": "darwin",
76
+ "osKernelVersionsSupported": ">=22",
77
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-macos14-arm64.tar.gz"
78
+ },
79
+ {
80
+ "version": "8.0.40",
81
+ "arch": "x64",
82
+ "os": "darwin",
83
+ "osKernelVersionsSupported": ">=22",
84
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-macos14-x86_64.tar.gz"
85
+ },
86
+ {
87
+ "version": "8.0.40",
88
+ "arch": "x64",
89
+ "os": "linux",
90
+ "osKernelVersionsSupported": "*",
91
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-linux-glibc2.17-x86_64-minimal.tar.xz"
92
+ },
93
+ {
94
+ "version": "8.0.40",
95
+ "arch": "arm64",
96
+ "os": "linux",
97
+ "osKernelVersionsSupported": "*",
98
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-linux-glibc2.17-aarch64-minimal.tar.xz"
99
+ },
100
+ {
101
+ "version": "8.0.40",
102
+ "arch": "x64",
103
+ "os": "win32",
104
+ "osKernelVersionsSupported": "*",
105
+ "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-winx64.zip"
106
+ },
2
107
  {
3
108
  "version": "9.0.1",
4
109
  "arch": "arm64",
@@ -1,23 +1,25 @@
1
1
  import { ExecFileException } from "child_process";
2
2
  export type LOG_LEVEL = 'LOG' | 'WARN' | 'ERROR';
3
3
  export type ServerOptions = {
4
- version?: string;
5
- dbName?: string;
6
- logLevel?: LOG_LEVEL;
7
- portRetries?: number;
8
- downloadBinaryOnce?: boolean;
9
- lockRetries?: number;
10
- lockRetryWait?: number;
11
- username?: string;
12
- deleteDBAfterStopped?: boolean;
13
- dbPath?: string;
14
- ignoreUnsupportedSystemVersion?: boolean;
15
- port?: number;
16
- xPort?: number;
17
- binaryDirectoryPath?: string;
4
+ version?: string | undefined;
5
+ dbName?: string | undefined;
6
+ logLevel?: LOG_LEVEL | undefined;
7
+ portRetries?: number | undefined;
8
+ downloadBinaryOnce?: boolean | undefined;
9
+ lockRetries?: number | undefined;
10
+ lockRetryWait?: number | undefined;
11
+ username?: string | undefined;
12
+ deleteDBAfterStopped?: boolean | undefined;
13
+ dbPath?: string | undefined;
14
+ ignoreUnsupportedSystemVersion?: boolean | undefined;
15
+ port?: number | undefined;
16
+ xPort?: number | undefined;
17
+ binaryDirectoryPath?: string | undefined;
18
+ downloadRetries?: number | undefined;
19
+ initSQLString?: string | undefined;
18
20
  };
19
21
  export type InternalServerOptions = {
20
- version?: string;
22
+ version?: string | undefined;
21
23
  dbName: string;
22
24
  logLevel: LOG_LEVEL;
23
25
  portRetries: number;
@@ -31,6 +33,8 @@ export type InternalServerOptions = {
31
33
  port: number;
32
34
  xPort: number;
33
35
  binaryDirectoryPath: string;
36
+ downloadRetries: number;
37
+ initSQLString: string;
34
38
  };
35
39
  export type ExecutorOptions = {
36
40
  logLevel: LOG_LEVEL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql-memory-server",
3
- "version": "1.4.3",
3
+ "version": "1.6.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",
@@ -16,27 +16,28 @@
16
16
  "memory database"
17
17
  ],
18
18
  "scripts": {
19
- "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose",
20
- "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose",
21
- "stress": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose"
19
+ "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors",
20
+ "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors",
21
+ "stress": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors"
22
22
  },
23
23
  "engines": {
24
- "node": ">=16.6.0"
24
+ "node": ">=16.6.0",
25
+ "bun": ">=1.0.0"
25
26
  },
26
27
  "author": "Sebastian-Webster",
27
28
  "license": "MIT",
28
29
  "devDependencies": {
29
- "@babel/core": "^7.24.9",
30
- "@babel/preset-env": "^7.25.4",
31
- "@babel/preset-typescript": "^7.24.7",
30
+ "@babel/core": "^7.25.9",
31
+ "@babel/preset-env": "^7.25.9",
32
+ "@babel/preset-typescript": "^7.25.9",
32
33
  "@types/adm-zip": "^0.5.5",
33
- "@types/node": "^22.5.4",
34
+ "@types/node": "^22.7.9",
34
35
  "@types/proper-lockfile": "^4.1.4",
35
36
  "@types/semver": "^7.5.8",
36
37
  "babel-jest": "^29.7.0",
37
38
  "jest": "^29.7.0",
38
- "mysql2": "^3.11.2",
39
- "typescript": "^5.6.2"
39
+ "mysql2": "^3.11.3",
40
+ "typescript": "^5.6.3"
40
41
  },
41
42
  "dependencies": {
42
43
  "adm-zip": "^0.5.16",