@13w/miri 1.1.4 → 1.1.6
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 +1 -1
- package/dist/evaluator.js +35 -44
- package/dist/miri.js +12 -11
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ const getMiri = async () => {
|
|
|
11
11
|
const opts = program.opts();
|
|
12
12
|
const client = await connection(opts.db);
|
|
13
13
|
return new Miri(client, {
|
|
14
|
-
localMigrations:
|
|
14
|
+
localMigrations: opts.migrations,
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
const stats = async (remote = false) => {
|
package/dist/evaluator.js
CHANGED
|
@@ -5,8 +5,6 @@ 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 connect from './mongodb.js';
|
|
9
|
-
const mongoClient = await connect();
|
|
10
8
|
const print = (values, type) => {
|
|
11
9
|
const prepare = (object, type = 'print') => {
|
|
12
10
|
if (type === 'print') {
|
|
@@ -25,53 +23,46 @@ const print = (values, type) => {
|
|
|
25
23
|
process.stdout.write('\n');
|
|
26
24
|
}
|
|
27
25
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
});
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
instanceState.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
await mongoClient.close();
|
|
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
|
+
const cliServiceProvider = new CliServiceProvider(client, bus, {
|
|
33
|
+
productName: 'MIRI: Migration manager',
|
|
34
|
+
productDocsLink: 'https://example.com/',
|
|
35
|
+
});
|
|
36
|
+
const instanceState = new ShellInstanceState(cliServiceProvider);
|
|
37
|
+
instanceState.setCtx(context);
|
|
38
|
+
instanceState.setEvaluationListener({
|
|
39
|
+
onPrint(values, type) {
|
|
40
|
+
return print(values, type);
|
|
41
|
+
},
|
|
42
|
+
onPrompt() {
|
|
43
|
+
throw new Error('Prompt isn\'t supported');
|
|
44
|
+
},
|
|
45
|
+
onLoad() {
|
|
46
|
+
throw new Error('Load isn\'t supported');
|
|
47
|
+
},
|
|
48
|
+
async onExit() {
|
|
49
|
+
throw new Error('Exit isn\'t supported');
|
|
50
|
+
},
|
|
51
|
+
});
|
|
59
52
|
const output = await new ShellEvaluator(instanceState)
|
|
60
|
-
.customEval(
|
|
61
|
-
// print([output])
|
|
53
|
+
.customEval(runInContext, `${code};`, context, filename);
|
|
62
54
|
return output.rawValue;
|
|
63
55
|
}
|
|
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
56
|
export async function evaluateJs(code, identifier = '[no file]') {
|
|
72
|
-
const context = createContext({ console });
|
|
57
|
+
const context = createContext({ __env, console });
|
|
73
58
|
const module = new SourceTextModule(code, { context, identifier });
|
|
74
|
-
await module.link(linker)
|
|
59
|
+
await module.link(async function linker(specifier, referencingModule) {
|
|
60
|
+
return import(specifier).then((module) => {
|
|
61
|
+
return new SyntheticModule(['default'], function () {
|
|
62
|
+
this.setExport('default', module.default);
|
|
63
|
+
}, { context: referencingModule.context });
|
|
64
|
+
});
|
|
65
|
+
});
|
|
75
66
|
await module.evaluate()
|
|
76
67
|
.catch((error) => {
|
|
77
68
|
error.message += ` # at file ${identifier}`;
|
package/dist/miri.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 } from 'node:path';
|
|
5
5
|
import { ObjectId } from 'mongodb';
|
|
6
6
|
import { evaluateJs, evaluateMongo } from './evaluator.js';
|
|
7
7
|
export var PatchStatus;
|
|
@@ -69,12 +69,12 @@ export default class Migrator {
|
|
|
69
69
|
localPatches.sort(sortPatches);
|
|
70
70
|
return localPatches;
|
|
71
71
|
}
|
|
72
|
-
async applyPatchContent(content, wrap = true) {
|
|
72
|
+
async applyPatchContent(content, filename, wrap = true) {
|
|
73
73
|
if (!content?.body) {
|
|
74
74
|
return -1;
|
|
75
75
|
}
|
|
76
76
|
const code = Buffer.from(content.body, 'base64').toString();
|
|
77
|
-
return evaluateMongo(wrap ? `(${code})();` : code)
|
|
77
|
+
return evaluateMongo(this.client, wrap ? `(${code})();` : code, filename)
|
|
78
78
|
.catch((error) => {
|
|
79
79
|
throw error;
|
|
80
80
|
}) ?? 0;
|
|
@@ -82,10 +82,11 @@ export default class Migrator {
|
|
|
82
82
|
async sync() {
|
|
83
83
|
const patches = await this.diff();
|
|
84
84
|
for (const patch of patches) {
|
|
85
|
+
const filename = `${patch.group}/${patch.name}`;
|
|
85
86
|
console.group(`Patch ${patch.group} / ${patch.name}...`);
|
|
86
87
|
if (patch.status === PatchStatus.Removed) {
|
|
87
88
|
console.group('Reverting changes');
|
|
88
|
-
const result = await this.applyPatchContent(patch.remoteContent?.down);
|
|
89
|
+
const result = await this.applyPatchContent(patch.remoteContent?.down, filename);
|
|
89
90
|
console.log(result === -1 ? 'Revert script not found' : 'done');
|
|
90
91
|
console.groupEnd();
|
|
91
92
|
await this.#collection.deleteOne({ _id: patch._id });
|
|
@@ -94,18 +95,18 @@ export default class Migrator {
|
|
|
94
95
|
}
|
|
95
96
|
if (patch.status === PatchStatus.Changed) {
|
|
96
97
|
console.group('Reverting changes');
|
|
97
|
-
const result = await this.applyPatchContent(patch.remoteContent?.down);
|
|
98
|
+
const result = await this.applyPatchContent(patch.remoteContent?.down, filename);
|
|
98
99
|
console.log(result === -1 ? 'Revert script not found' : 'done');
|
|
99
100
|
console.groupEnd();
|
|
100
101
|
patch.status = PatchStatus.New;
|
|
101
102
|
}
|
|
102
103
|
if (patch.status === PatchStatus.New) {
|
|
103
104
|
console.group('Testing migration');
|
|
104
|
-
const test = await this.applyPatchContent(patch.content.test);
|
|
105
|
+
const test = await this.applyPatchContent(patch.content.test, filename);
|
|
105
106
|
console.log(`degradation level: ${test}`);
|
|
106
107
|
if (test !== 0) {
|
|
107
108
|
console.group('Applying migration...');
|
|
108
|
-
await this.applyPatchContent(patch.content.up);
|
|
109
|
+
await this.applyPatchContent(patch.content.up, filename);
|
|
109
110
|
console.log('Done');
|
|
110
111
|
console.groupEnd();
|
|
111
112
|
}
|
|
@@ -126,7 +127,7 @@ export default class Migrator {
|
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
async getLocalPatches(raw = false, group = '', name = '') {
|
|
129
|
-
const migrationsDir = await realpath(
|
|
130
|
+
const migrationsDir = await realpath(resolve(process.cwd(), this.#options.localMigrations ?? 'migrations'));
|
|
130
131
|
console.debug(`Reading ${migrationsDir}...`);
|
|
131
132
|
const files = await readdir(migrationsDir, { recursive: true, withFileTypes: true });
|
|
132
133
|
const patches = [];
|
|
@@ -147,7 +148,7 @@ export default class Migrator {
|
|
|
147
148
|
continue;
|
|
148
149
|
}
|
|
149
150
|
patches.push(patchObject);
|
|
150
|
-
const patchContent = await readFile(
|
|
151
|
+
const patchContent = await readFile(resolve(process.cwd(), file.path, file.name));
|
|
151
152
|
if (raw) {
|
|
152
153
|
patchObject.raw = patchContent.toString('base64');
|
|
153
154
|
continue;
|
|
@@ -218,7 +219,7 @@ export default class Migrator {
|
|
|
218
219
|
continue;
|
|
219
220
|
}
|
|
220
221
|
console.log('applying');
|
|
221
|
-
await this.applyPatchContent({ body: patch.raw, hash: '' }, false);
|
|
222
|
+
await this.applyPatchContent({ body: patch.raw, hash: '' }, `${patch.group}/${patch.name}`, false);
|
|
222
223
|
await this.#collection.insertOne({
|
|
223
224
|
group: patch.group,
|
|
224
225
|
name: patch.name,
|
|
@@ -232,7 +233,7 @@ export default class Migrator {
|
|
|
232
233
|
const patches = await (remote ? this.getRemotePatches() : this.diff());
|
|
233
234
|
for (const patch of patches) {
|
|
234
235
|
patch.status = patch.status ?? PatchStatus.Ok;
|
|
235
|
-
const degradation = await this.applyPatchContent(patch.content.test);
|
|
236
|
+
const degradation = await this.applyPatchContent(patch.content.test, `${patch.group}/${patch.name}`);
|
|
236
237
|
patch.degradation = degradation === -1 ? '-' : degradation;
|
|
237
238
|
if (degradation > 0 && [PatchStatus.Ok, PatchStatus.Updated].includes(patch.status)) {
|
|
238
239
|
patch.status = PatchStatus.Degraded;
|
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.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "v20"
|
|
@@ -40,6 +40,6 @@
|
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -p tsconfig.json",
|
|
42
42
|
"lint": "eslint src/ --ext .ts --quiet",
|
|
43
|
-
"
|
|
43
|
+
"prepublish": "pnpm run build"
|
|
44
44
|
}
|
|
45
45
|
}
|