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 +24 -4
- package/dist/src/index.js +3 -1
- package/dist/src/libraries/Downloader.js +95 -43
- package/dist/src/libraries/Executor.d.ts +0 -1
- package/dist/src/libraries/Executor.js +29 -27
- package/dist/src/versions.json +105 -0
- package/dist/types/index.d.ts +19 -15
- package/package.json +12 -11
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
await extractBinary(url, archivePath, extractedPath, logger);
|
|
216
|
-
}
|
|
217
|
-
catch (e) {
|
|
237
|
+
let downloadTries = 0;
|
|
238
|
+
do {
|
|
218
239
|
try {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
226
|
-
}
|
|
227
|
-
finally {
|
|
246
|
+
//Delete generated files since either download or extraction failed
|
|
228
247
|
try {
|
|
229
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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');
|
package/dist/src/versions.json
CHANGED
|
@@ -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",
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
30
|
-
"@babel/preset-env": "^7.25.
|
|
31
|
-
"@babel/preset-typescript": "^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.
|
|
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.
|
|
39
|
-
"typescript": "^5.6.
|
|
39
|
+
"mysql2": "^3.11.3",
|
|
40
|
+
"typescript": "^5.6.3"
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
43
|
"adm-zip": "^0.5.16",
|