@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 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: program.opts().migrations,
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 bus = new EventEmitter();
29
- const cliServiceProvider = new CliServiceProvider(mongoClient, bus, {
30
- productName: 'MIRI: Migration manager',
31
- productDocsLink: 'https://example.com/',
32
- });
33
- const context = createContext({
34
- __env: Object.fromEntries(Object.entries(process.env)
35
- .filter(([key]) => key.startsWith('MIRI_'))
36
- .map(([key, value]) => [key.substring(5), value])),
37
- });
38
- const originalEval = (code) => runInContext(code, context);
39
- const instanceState = new ShellInstanceState(cliServiceProvider);
40
- instanceState.setCtx(context);
41
- instanceState.setEvaluationListener({
42
- onPrint(values, type) {
43
- // console.dir(['onPrint', type, values])
44
- return print(values, type);
45
- },
46
- onPrompt() {
47
- throw new Error('Prompt isn\'t supported');
48
- },
49
- onLoad() {
50
- throw new Error('Load isn\'t supported');
51
- },
52
- async onExit(exitCode) {
53
- process.stdout.write(`onExit: ${exitCode}\n`);
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(originalEval, `${code};`, context, filename);
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 { join } from 'node:path';
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(join(process.cwd(), this.#options.localMigrations ?? 'migrations'));
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(join(file.path, file.name));
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",
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
- "postinstall": "pnpm run build"
43
+ "prepublish": "pnpm run build"
44
44
  }
45
45
  }