@13w/miri 1.1.5 → 1.1.7
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/dist/cli.js +75 -9
- package/dist/evaluator.js +38 -46
- package/dist/miri.js +94 -20
- package/dist/mongodb.js +5 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
Error.stackTraceLimit = Infinity;
|
|
1
2
|
import { join } from 'node:path';
|
|
2
3
|
/* eslint-disable no-console */
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
import { Table } from 'console-table-printer';
|
|
6
|
+
import colors from 'colors';
|
|
5
7
|
import connection from './mongodb.js';
|
|
6
|
-
import Miri, { PatchStatus } from './miri.js';
|
|
8
|
+
import Miri, { IndexStatus, PatchStatus } from './miri.js';
|
|
7
9
|
const program = new Command();
|
|
8
10
|
program.option('-m --migrations <folder>', 'Folder with migrations', join(process.cwd(), 'migrations'));
|
|
9
11
|
program.option('-d --db <mongo-uri>', 'MongoDB Connection URI', 'mongodb://localhost:27017/test');
|
|
@@ -11,10 +13,10 @@ const getMiri = async () => {
|
|
|
11
13
|
const opts = program.opts();
|
|
12
14
|
const client = await connection(opts.db);
|
|
13
15
|
return new Miri(client, {
|
|
14
|
-
localMigrations:
|
|
16
|
+
localMigrations: opts.migrations,
|
|
15
17
|
});
|
|
16
18
|
};
|
|
17
|
-
const
|
|
19
|
+
const status = async (remote = false) => {
|
|
18
20
|
const miri = await getMiri();
|
|
19
21
|
const patches = await miri.stat(remote);
|
|
20
22
|
await miri[Symbol.asyncDispose]();
|
|
@@ -42,9 +44,9 @@ const stats = async (remote = false) => {
|
|
|
42
44
|
}
|
|
43
45
|
table.printTable();
|
|
44
46
|
};
|
|
45
|
-
program.command('
|
|
47
|
+
program.command('status')
|
|
46
48
|
.description('Displays list of applied migrations')
|
|
47
|
-
.action(() =>
|
|
49
|
+
.action(() => status(true));
|
|
48
50
|
const initProgram = program.command('init');
|
|
49
51
|
initProgram.command('apply')
|
|
50
52
|
.action(async () => {
|
|
@@ -56,16 +58,80 @@ initProgram.command('status')
|
|
|
56
58
|
.action(() => {
|
|
57
59
|
console.log('There should be init status....');
|
|
58
60
|
});
|
|
61
|
+
const indexesProgram = program.command('indexes')
|
|
62
|
+
.command('status')
|
|
63
|
+
.argument('[collection]', 'MongoDB Collection name')
|
|
64
|
+
.option('-q --quiet', 'Show only changes', false)
|
|
65
|
+
.action(async () => {
|
|
66
|
+
const collection = indexesProgram.args[0];
|
|
67
|
+
const { quiet } = indexesProgram.opts();
|
|
68
|
+
const miri = await getMiri();
|
|
69
|
+
const structure = await miri.indexesDiff(collection);
|
|
70
|
+
await miri[Symbol.asyncDispose]();
|
|
71
|
+
for (const [collection, indexes] of Object.entries(structure)) {
|
|
72
|
+
let changes = false;
|
|
73
|
+
for (const [name, detail] of Object.entries(indexes)) {
|
|
74
|
+
if (quiet && detail.status === IndexStatus.Applied) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const color = {
|
|
78
|
+
[IndexStatus.New]: colors.green,
|
|
79
|
+
[IndexStatus.Applied]: colors.white,
|
|
80
|
+
[IndexStatus.Removed]: colors.red,
|
|
81
|
+
}[detail.status];
|
|
82
|
+
const point = {
|
|
83
|
+
[IndexStatus.New]: colors.green.bold('+ '),
|
|
84
|
+
[IndexStatus.Applied]: colors.cyan('\u00b7 '),
|
|
85
|
+
[IndexStatus.Removed]: colors.red.bold('- '),
|
|
86
|
+
}[detail.status];
|
|
87
|
+
if (!changes) {
|
|
88
|
+
console.group(colors.bold(`Collection ${collection}:`));
|
|
89
|
+
changes = true;
|
|
90
|
+
}
|
|
91
|
+
console.log(color(`${point}${name}`));
|
|
92
|
+
}
|
|
93
|
+
console.groupEnd();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
indexesProgram.command('sync')
|
|
97
|
+
.option('<collection>', 'MongoDB Collection name', '')
|
|
98
|
+
.action(async () => {
|
|
99
|
+
const miri = await getMiri();
|
|
100
|
+
let group = '';
|
|
101
|
+
console.group('Starting synchronisation...', indexesProgram.opts());
|
|
102
|
+
for await (const { collection, status, name, error } of miri.indexesSync()) {
|
|
103
|
+
if (group !== collection) {
|
|
104
|
+
if (group) {
|
|
105
|
+
console.log('Done');
|
|
106
|
+
console.groupEnd();
|
|
107
|
+
}
|
|
108
|
+
group = collection;
|
|
109
|
+
console.group(`Collection: ${collection}...`);
|
|
110
|
+
}
|
|
111
|
+
if (status === IndexStatus.Applied) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
console[error ? 'group' : 'log'](`${status === IndexStatus.New ? 'Creating' : 'Removing'} index ${name}... ${error ? 'failed' : 'done'}`);
|
|
115
|
+
if (error) {
|
|
116
|
+
console.log(colors.red(error.message));
|
|
117
|
+
console.groupEnd();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
console.groupEnd();
|
|
121
|
+
await miri[Symbol.asyncDispose]();
|
|
122
|
+
});
|
|
59
123
|
program.command('diff')
|
|
60
124
|
.description('Displays difference between local and applied migrations')
|
|
61
|
-
.action(() =>
|
|
62
|
-
program.command('sync')
|
|
125
|
+
.action(() => status());
|
|
126
|
+
const programSync = program.command('sync')
|
|
127
|
+
.option('--remote', 'Remote only')
|
|
128
|
+
.option('--degraded', 'Re-apply patches on degraded migrations')
|
|
129
|
+
.option('--all', 'Re-apply all patches')
|
|
63
130
|
.description('Applies migrations')
|
|
64
131
|
.action(async () => {
|
|
65
132
|
const miri = await getMiri();
|
|
66
|
-
await miri.sync();
|
|
133
|
+
await miri.sync(programSync.opts());
|
|
67
134
|
await miri[Symbol.asyncDispose]();
|
|
68
135
|
});
|
|
69
136
|
program.parse();
|
|
70
|
-
const opts = program.opts();
|
|
71
137
|
//# sourceMappingURL=cli.js.map
|
package/dist/evaluator.js
CHANGED
|
@@ -5,8 +5,7 @@ import { inspect } from 'node:util';
|
|
|
5
5
|
import { CliServiceProvider } from '@mongosh/service-provider-server';
|
|
6
6
|
import { ShellInstanceState } from '@mongosh/shell-api';
|
|
7
7
|
import { ShellEvaluator } from '@mongosh/shell-evaluator';
|
|
8
|
-
import
|
|
9
|
-
const mongoClient = await connect();
|
|
8
|
+
import colors from 'colors';
|
|
10
9
|
const print = (values, type) => {
|
|
11
10
|
const prepare = (object, type = 'print') => {
|
|
12
11
|
if (type === 'print') {
|
|
@@ -21,57 +20,50 @@ const print = (values, type) => {
|
|
|
21
20
|
if (printable === void 0) {
|
|
22
21
|
continue;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
process.stdout.write('\n');
|
|
23
|
+
console.log(colors.blue(prepare(printable, value.type ?? type)));
|
|
26
24
|
}
|
|
27
25
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const instanceState = new ShellInstanceState(cliServiceProvider);
|
|
40
|
-
instanceState.setCtx(context);
|
|
41
|
-
instanceState.setEvaluationListener({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
process.exit(exitCode);
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
export async function evaluateMongo(code, filename = '[no file]') {
|
|
26
|
+
const __env = Object.fromEntries(Object.entries(process.env)
|
|
27
|
+
.filter(([key]) => key.startsWith('MIRI_'))
|
|
28
|
+
.map(([key, value]) => [key.substring(5), value]));
|
|
29
|
+
export async function evaluateMongo(client, code, filename = '[no file]') {
|
|
30
|
+
const context = createContext({ __env });
|
|
31
|
+
const bus = new EventEmitter();
|
|
32
|
+
// console.log(`Client status! ${(<{ topology: { isConnected: () => boolean } } & MongoClient>client)?.topology?.isConnected() ? '' : 'not'} connected`)
|
|
33
|
+
const cliServiceProvider = new CliServiceProvider(client, bus, {
|
|
34
|
+
productName: 'MIRI: Migration manager',
|
|
35
|
+
productDocsLink: 'https://example.com/',
|
|
36
|
+
});
|
|
37
|
+
const instanceState = new ShellInstanceState(cliServiceProvider);
|
|
38
|
+
instanceState.setCtx(context);
|
|
39
|
+
instanceState.setEvaluationListener({
|
|
40
|
+
onPrint(values, type) {
|
|
41
|
+
return print(values, type);
|
|
42
|
+
},
|
|
43
|
+
onPrompt() {
|
|
44
|
+
throw new Error('Prompt isn\'t supported');
|
|
45
|
+
},
|
|
46
|
+
onLoad() {
|
|
47
|
+
throw new Error('Load isn\'t supported');
|
|
48
|
+
},
|
|
49
|
+
async onExit() {
|
|
50
|
+
throw new Error('Exit isn\'t supported');
|
|
51
|
+
},
|
|
52
|
+
});
|
|
59
53
|
const output = await new ShellEvaluator(instanceState)
|
|
60
|
-
.customEval(
|
|
61
|
-
// print([output])
|
|
54
|
+
.customEval(runInContext, `${code};`, context, filename);
|
|
62
55
|
return output.rawValue;
|
|
63
56
|
}
|
|
64
|
-
async function linker(specifier, referencingModule) {
|
|
65
|
-
return import(specifier).then((module) => {
|
|
66
|
-
return new SyntheticModule(['default'], function () {
|
|
67
|
-
this.setExport('default', module.default);
|
|
68
|
-
}, { context: referencingModule.context });
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
57
|
export async function evaluateJs(code, identifier = '[no file]') {
|
|
72
|
-
const context = createContext({ console });
|
|
58
|
+
const context = createContext({ __env, console });
|
|
73
59
|
const module = new SourceTextModule(code, { context, identifier });
|
|
74
|
-
await module.link(linker)
|
|
60
|
+
await module.link(async function linker(specifier, referencingModule) {
|
|
61
|
+
return import(specifier).then((module) => {
|
|
62
|
+
return new SyntheticModule(['default'], function () {
|
|
63
|
+
this.setExport('default', module.default);
|
|
64
|
+
}, { context: referencingModule.context });
|
|
65
|
+
});
|
|
66
|
+
});
|
|
75
67
|
await module.evaluate()
|
|
76
68
|
.catch((error) => {
|
|
77
69
|
error.message += ` # at file ${identifier}`;
|
package/dist/miri.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { readdir, readFile, realpath } from 'node:fs/promises';
|
|
4
|
-
import {
|
|
4
|
+
import { resolve, extname, basename } from 'node:path';
|
|
5
5
|
import { ObjectId } from 'mongodb';
|
|
6
6
|
import { evaluateJs, evaluateMongo } from './evaluator.js';
|
|
7
|
+
import colors from 'colors';
|
|
7
8
|
export var PatchStatus;
|
|
8
9
|
(function (PatchStatus) {
|
|
9
10
|
PatchStatus[PatchStatus["Ok"] = 0] = "Ok";
|
|
@@ -13,6 +14,12 @@ export var PatchStatus;
|
|
|
13
14
|
PatchStatus[PatchStatus["Removed"] = 4] = "Removed";
|
|
14
15
|
PatchStatus[PatchStatus["Degraded"] = 5] = "Degraded";
|
|
15
16
|
})(PatchStatus || (PatchStatus = {}));
|
|
17
|
+
export var IndexStatus;
|
|
18
|
+
(function (IndexStatus) {
|
|
19
|
+
IndexStatus[IndexStatus["New"] = 0] = "New";
|
|
20
|
+
IndexStatus[IndexStatus["Applied"] = 1] = "Applied";
|
|
21
|
+
IndexStatus[IndexStatus["Removed"] = 2] = "Removed";
|
|
22
|
+
})(IndexStatus || (IndexStatus = {}));
|
|
16
23
|
const sortPatches = (a, b) => {
|
|
17
24
|
if (a.group === b.group) {
|
|
18
25
|
return a.name < b.name ? -1 : 1;
|
|
@@ -69,23 +76,25 @@ export default class Migrator {
|
|
|
69
76
|
localPatches.sort(sortPatches);
|
|
70
77
|
return localPatches;
|
|
71
78
|
}
|
|
72
|
-
async applyPatchContent(content, wrap = true) {
|
|
79
|
+
async applyPatchContent(content, filename, wrap = true) {
|
|
73
80
|
if (!content?.body) {
|
|
74
81
|
return -1;
|
|
75
82
|
}
|
|
76
83
|
const code = Buffer.from(content.body, 'base64').toString();
|
|
77
|
-
return evaluateMongo(wrap ? `(${code})();` : code)
|
|
84
|
+
return evaluateMongo(this.client, wrap ? `(async ${code})();` : code, filename)
|
|
78
85
|
.catch((error) => {
|
|
79
86
|
throw error;
|
|
80
87
|
}) ?? 0;
|
|
81
88
|
}
|
|
82
|
-
async sync() {
|
|
83
|
-
const patches = await this.diff();
|
|
89
|
+
async sync({ remote = false, all = false, degraded = false } = {}) {
|
|
90
|
+
const patches = remote ? await this.getRemotePatches() : await this.diff();
|
|
91
|
+
// console.log(`Sync: remote: ${remote ? 'on' : 'off'} | all: ${all ? 'on' : 'off'} | degraded: ${degraded ? 'on' : 'off'}`)
|
|
84
92
|
for (const patch of patches) {
|
|
93
|
+
const filename = `${patch.group}/${patch.name}`;
|
|
85
94
|
console.group(`Patch ${patch.group} / ${patch.name}...`);
|
|
86
95
|
if (patch.status === PatchStatus.Removed) {
|
|
87
96
|
console.group('Reverting changes');
|
|
88
|
-
const result = await this.applyPatchContent(patch.remoteContent?.down);
|
|
97
|
+
const result = await this.applyPatchContent(patch.remoteContent?.down, filename);
|
|
89
98
|
console.log(result === -1 ? 'Revert script not found' : 'done');
|
|
90
99
|
console.groupEnd();
|
|
91
100
|
await this.#collection.deleteOne({ _id: patch._id });
|
|
@@ -94,23 +103,23 @@ export default class Migrator {
|
|
|
94
103
|
}
|
|
95
104
|
if (patch.status === PatchStatus.Changed) {
|
|
96
105
|
console.group('Reverting changes');
|
|
97
|
-
const result = await this.applyPatchContent(patch.remoteContent?.down);
|
|
106
|
+
const result = await this.applyPatchContent(patch.remoteContent?.down, filename);
|
|
98
107
|
console.log(result === -1 ? 'Revert script not found' : 'done');
|
|
99
108
|
console.groupEnd();
|
|
100
109
|
patch.status = PatchStatus.New;
|
|
101
110
|
}
|
|
102
|
-
if (patch.status === PatchStatus.New) {
|
|
103
|
-
console.group('Testing migration');
|
|
104
|
-
const test = await this.applyPatchContent(patch.content.test);
|
|
105
|
-
console.log(`degradation level: ${test}`);
|
|
106
|
-
if (test !== 0) {
|
|
107
|
-
console.group('Applying migration...');
|
|
108
|
-
await this.applyPatchContent(patch.content.up);
|
|
109
|
-
console.log('Done');
|
|
111
|
+
if (all || degraded || patch.status === PatchStatus.New) {
|
|
112
|
+
console.group(colors.white('Testing migration'));
|
|
113
|
+
const test = await this.applyPatchContent(patch.content.test, filename);
|
|
114
|
+
console.log(colors.white(`degradation level: ${test}`));
|
|
115
|
+
if (all || test !== 0) {
|
|
116
|
+
console.group(colors.cyan('Applying migration...'));
|
|
117
|
+
await this.applyPatchContent(patch.content.up, filename);
|
|
118
|
+
console.log(colors.green('Done'));
|
|
110
119
|
console.groupEnd();
|
|
111
120
|
}
|
|
112
121
|
else {
|
|
113
|
-
console.log('nothing to apply');
|
|
122
|
+
console.log(colors.green('nothing to apply'));
|
|
114
123
|
}
|
|
115
124
|
console.groupEnd();
|
|
116
125
|
}
|
|
@@ -126,7 +135,7 @@ export default class Migrator {
|
|
|
126
135
|
}
|
|
127
136
|
}
|
|
128
137
|
async getLocalPatches(raw = false, group = '', name = '') {
|
|
129
|
-
const migrationsDir = await realpath(
|
|
138
|
+
const migrationsDir = await realpath(resolve(process.cwd(), this.#options.localMigrations ?? 'migrations'));
|
|
130
139
|
console.debug(`Reading ${migrationsDir}...`);
|
|
131
140
|
const files = await readdir(migrationsDir, { recursive: true, withFileTypes: true });
|
|
132
141
|
const patches = [];
|
|
@@ -134,10 +143,15 @@ export default class Migrator {
|
|
|
134
143
|
if (!file.isFile()) {
|
|
135
144
|
continue;
|
|
136
145
|
}
|
|
146
|
+
const extension = extname(file.name);
|
|
147
|
+
if (!['.js', '.json'].includes(extension)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
137
150
|
const patchObject = {
|
|
138
151
|
_id: new ObjectId(),
|
|
139
152
|
group: file.path.substring(migrationsDir.length + 1),
|
|
140
153
|
name: file.name,
|
|
154
|
+
title: basename(file.name, extension),
|
|
141
155
|
content: {},
|
|
142
156
|
};
|
|
143
157
|
if (group ? patchObject.group !== group : ['init', 'indexes'].includes(patchObject.group)) {
|
|
@@ -147,7 +161,7 @@ export default class Migrator {
|
|
|
147
161
|
continue;
|
|
148
162
|
}
|
|
149
163
|
patches.push(patchObject);
|
|
150
|
-
const patchContent = await readFile(
|
|
164
|
+
const patchContent = await readFile(resolve(process.cwd(), file.path, file.name));
|
|
151
165
|
if (raw) {
|
|
152
166
|
patchObject.raw = patchContent.toString('base64');
|
|
153
167
|
continue;
|
|
@@ -201,6 +215,66 @@ export default class Migrator {
|
|
|
201
215
|
patches.sort(sortPatches);
|
|
202
216
|
return patches;
|
|
203
217
|
}
|
|
218
|
+
async indexesDiff(collection) {
|
|
219
|
+
const localIndexes = await this.getLocalPatches(true, 'indexes', collection && `${collection}.json`);
|
|
220
|
+
const structure = {};
|
|
221
|
+
const db = this.#client.db();
|
|
222
|
+
for (const patch of localIndexes) {
|
|
223
|
+
const indexes = JSON.parse(Buffer.from(patch.raw, 'base64').toString());
|
|
224
|
+
structure[patch.title] = {};
|
|
225
|
+
const collection = structure[patch.title];
|
|
226
|
+
// console.log(`Reading indexes from ${patch.title}...`)
|
|
227
|
+
const remoteIndexes = await db.collection(patch.title).indexes({ full: true })
|
|
228
|
+
.catch(() => []);
|
|
229
|
+
// console.dir([patch.title, remoteIndexes], { colors: true, customInspect: true, depth: 22 })
|
|
230
|
+
for (const index of indexes) {
|
|
231
|
+
// noinspection SuspiciousTypeOfGuard
|
|
232
|
+
if (typeof index === 'string') {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const [key, options] = (Array.isArray(index) ? index : [index, {}]);
|
|
236
|
+
const name = Object.entries(key).reduce((result, [key, value]) => `${result ? `${result}_` : ''}${key}_${value}`, '');
|
|
237
|
+
const remoteIndex = remoteIndexes.find(({ name: indexName }) => indexName === name);
|
|
238
|
+
collection[name] = { key, options, status: remoteIndex ? IndexStatus.Applied : IndexStatus.New };
|
|
239
|
+
if (remoteIndex) {
|
|
240
|
+
remoteIndexes.splice(remoteIndexes.indexOf(remoteIndex), 1);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (remoteIndexes.length) {
|
|
244
|
+
for (const index of remoteIndexes) {
|
|
245
|
+
if (index.name === '_id_') {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
collection[index.name] = { key: index.key, options: index, status: IndexStatus.Removed };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return structure;
|
|
253
|
+
}
|
|
254
|
+
async *indexesSync(collection) {
|
|
255
|
+
const structure = await this.indexesDiff(collection);
|
|
256
|
+
const db = this.#client.db();
|
|
257
|
+
for (const [collection, indexes] of Object.entries(structure)) {
|
|
258
|
+
const coll = db.collection(collection);
|
|
259
|
+
for (const [name, { key, status, options }] of Object.entries(indexes)) {
|
|
260
|
+
if (status === IndexStatus.Removed) {
|
|
261
|
+
const error = await coll.dropIndex(name)
|
|
262
|
+
.then(() => { })
|
|
263
|
+
.catch((error) => error);
|
|
264
|
+
yield { collection, name, error, status };
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (status === IndexStatus.New) {
|
|
268
|
+
const error = await coll.createIndex(key, options)
|
|
269
|
+
.then(() => { })
|
|
270
|
+
.catch((error) => error);
|
|
271
|
+
yield { collection, name, error, status };
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
yield { collection, name, status };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
204
278
|
async init() {
|
|
205
279
|
const localInits = await this.getLocalPatches(true, 'init');
|
|
206
280
|
const remoteInits = await this.getRemotePatches('init');
|
|
@@ -218,7 +292,7 @@ export default class Migrator {
|
|
|
218
292
|
continue;
|
|
219
293
|
}
|
|
220
294
|
console.log('applying');
|
|
221
|
-
await this.applyPatchContent({ body: patch.raw, hash: '' }, false);
|
|
295
|
+
await this.applyPatchContent({ body: patch.raw, hash: '' }, `${patch.group}/${patch.name}`, false);
|
|
222
296
|
await this.#collection.insertOne({
|
|
223
297
|
group: patch.group,
|
|
224
298
|
name: patch.name,
|
|
@@ -232,7 +306,7 @@ export default class Migrator {
|
|
|
232
306
|
const patches = await (remote ? this.getRemotePatches() : this.diff());
|
|
233
307
|
for (const patch of patches) {
|
|
234
308
|
patch.status = patch.status ?? PatchStatus.Ok;
|
|
235
|
-
const degradation = await this.applyPatchContent(patch.content.test);
|
|
309
|
+
const degradation = await this.applyPatchContent(patch.content.test, `${patch.group}/${patch.name}`);
|
|
236
310
|
patch.degradation = degradation === -1 ? '-' : degradation;
|
|
237
311
|
if (degradation > 0 && [PatchStatus.Ok, PatchStatus.Updated].includes(patch.status)) {
|
|
238
312
|
patch.status = PatchStatus.Degraded;
|
package/dist/mongodb.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { MongoClient } from 'mongodb';
|
|
2
2
|
let client;
|
|
3
3
|
export default async function connect(uri = 'mongodb://localhost:27017/test') {
|
|
4
|
-
|
|
4
|
+
if (!client) {
|
|
5
|
+
client = await new MongoClient(uri).connect();
|
|
6
|
+
client?.topology?.socket?.unref();
|
|
7
|
+
}
|
|
8
|
+
return client;
|
|
5
9
|
}
|
|
6
10
|
//# sourceMappingURL=mongodb.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@13w/miri",
|
|
3
3
|
"description": "MongoDB patch manager",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.7",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "v20"
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"@mongosh/service-provider-server": "^2.1.5",
|
|
24
24
|
"@mongosh/shell-api": "^2.1.5",
|
|
25
25
|
"@mongosh/shell-evaluator": "^2.1.5",
|
|
26
|
+
"colors": "^1.4.0",
|
|
26
27
|
"commander": "^12.0.0",
|
|
27
28
|
"console-table-printer": "^2.12.0",
|
|
28
29
|
"mongodb": "^6.3.0"
|