@13w/miri 1.1.9 → 1.1.10
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 +42 -13
- package/dist/mongodb.js +1 -1
- package/package.json +7 -6
package/dist/cli.js
CHANGED
|
@@ -4,14 +4,45 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { Table } from 'console-table-printer';
|
|
6
6
|
import colors from 'colors';
|
|
7
|
+
import { createTunnel } from 'tunnel-ssh';
|
|
7
8
|
import connection from './mongodb.js';
|
|
8
9
|
import Miri, { IndexStatus, PatchStatus } from './miri.js';
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import { realpathSync } from 'node:fs';
|
|
12
|
+
const { MIRI_MONGO_URI = 'mongodb://localhost:27017/test', SSH_AUTH_SOCK } = process.env;
|
|
9
13
|
const program = new Command();
|
|
10
14
|
program.option('-m --migrations <folder>', 'Folder with migrations', join(process.cwd(), 'migrations'));
|
|
11
|
-
program.option('-d --db <mongo-uri>', 'MongoDB Connection URI',
|
|
15
|
+
program.option('-d --db <mongo-uri>', 'MongoDB Connection URI', MIRI_MONGO_URI);
|
|
16
|
+
program.option('--ssh-host <host>', 'Connect via SSH proxy Host');
|
|
17
|
+
program.option('--ssh-port <port>', 'Connect via SSH proxy Port');
|
|
18
|
+
program.option('--ssh-user <user>', 'Connect via SSH proxy User');
|
|
19
|
+
program.option('--ssh-key <path/to/key>', 'Connect via SSH proxy IdentityKey');
|
|
20
|
+
const createSSHTunnel = async (opts) => {
|
|
21
|
+
const sshOptions = {
|
|
22
|
+
host: opts.sshHost,
|
|
23
|
+
port: Number(opts.sshPort ?? 22),
|
|
24
|
+
username: opts.sshUser,
|
|
25
|
+
agent: SSH_AUTH_SOCK,
|
|
26
|
+
privateKey: opts.sshKey ? readFileSync(realpathSync(opts.sshKey)) : void 0,
|
|
27
|
+
};
|
|
28
|
+
const dst = new URL(opts.db);
|
|
29
|
+
const forwardOptions = {
|
|
30
|
+
dstPort: Number(dst.port ?? 27017),
|
|
31
|
+
dstAddr: dst.hostname,
|
|
32
|
+
};
|
|
33
|
+
const [server] = await createTunnel({ autoClose: true }, {}, sshOptions, forwardOptions);
|
|
34
|
+
const addressInfo = server.address();
|
|
35
|
+
dst.host = addressInfo.family === 'IPv6' ? `[${String(addressInfo.address)}]` : String(addressInfo.address);
|
|
36
|
+
dst.port = String(addressInfo.port);
|
|
37
|
+
return dst.toString();
|
|
38
|
+
};
|
|
12
39
|
const getMiri = async () => {
|
|
13
40
|
const opts = program.opts();
|
|
14
|
-
const
|
|
41
|
+
const db = opts.sshHost ? await createSSHTunnel(opts) : opts.db;
|
|
42
|
+
const dbUri = new URL(db);
|
|
43
|
+
dbUri.searchParams.append('directConnection', 'true');
|
|
44
|
+
dbUri.searchParams.append('appName', 'miri+v1');
|
|
45
|
+
const client = await connection(dbUri.toString());
|
|
15
46
|
return new Miri(client, {
|
|
16
47
|
localMigrations: opts.migrations,
|
|
17
48
|
});
|
|
@@ -59,12 +90,10 @@ initProgram.command('status')
|
|
|
59
90
|
.action(() => status(false, 'init'));
|
|
60
91
|
const indexesProgram = program.command('indexes')
|
|
61
92
|
.description('Manage indexes');
|
|
62
|
-
|
|
93
|
+
indexesProgram.command('status')
|
|
63
94
|
.argument('[collection]', 'MongoDB Collection name')
|
|
64
95
|
.option('-q --quiet', 'Show only changes', false)
|
|
65
|
-
.action(async () => {
|
|
66
|
-
const collection = indexStatusProgram.args[0];
|
|
67
|
-
const { quiet } = indexStatusProgram.opts();
|
|
96
|
+
.action(async (collection, { quiet }) => {
|
|
68
97
|
const miri = await getMiri();
|
|
69
98
|
const structure = await miri.indexesDiff(collection);
|
|
70
99
|
await miri[Symbol.asyncDispose]();
|
|
@@ -94,12 +123,12 @@ const indexStatusProgram = indexesProgram.command('status')
|
|
|
94
123
|
}
|
|
95
124
|
});
|
|
96
125
|
const indexSyncProgram = indexesProgram.command('sync');
|
|
97
|
-
indexSyncProgram.
|
|
98
|
-
.action(async () => {
|
|
126
|
+
indexSyncProgram.argument('[collection]', 'MongoDB Collection name', '')
|
|
127
|
+
.action(async (coll) => {
|
|
99
128
|
const miri = await getMiri();
|
|
100
129
|
let group = '';
|
|
101
130
|
console.group('Starting synchronisation...');
|
|
102
|
-
for await (const { collection, status, name, error } of miri.indexesSync(
|
|
131
|
+
for await (const { collection, status, name, error } of miri.indexesSync(coll)) {
|
|
103
132
|
if (group !== collection) {
|
|
104
133
|
if (group) {
|
|
105
134
|
console.log('Done');
|
|
@@ -122,17 +151,17 @@ indexSyncProgram.option('<collection>', 'MongoDB Collection name', '')
|
|
|
122
151
|
});
|
|
123
152
|
const patchProgram = program.command('patch')
|
|
124
153
|
.description('Applies patch to database');
|
|
125
|
-
|
|
154
|
+
patchProgram.command('diff')
|
|
126
155
|
.description('Displays difference between local and applied migrations')
|
|
127
156
|
.action(() => status());
|
|
128
|
-
|
|
157
|
+
patchProgram.command('sync')
|
|
129
158
|
.description('Applies migrations')
|
|
130
159
|
.option('--remote', 'Remote only')
|
|
131
160
|
.option('--degraded', 'Re-apply patches on degraded migrations')
|
|
132
161
|
.option('--all', 'Re-apply all patches')
|
|
133
|
-
.action(async () => {
|
|
162
|
+
.action(async (opts) => {
|
|
134
163
|
const miri = await getMiri();
|
|
135
|
-
await miri.sync(
|
|
164
|
+
await miri.sync(opts);
|
|
136
165
|
await miri[Symbol.asyncDispose]();
|
|
137
166
|
});
|
|
138
167
|
program.parse();
|
package/dist/mongodb.js
CHANGED
|
@@ -2,7 +2,7 @@ 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
|
|
5
|
+
client = await MongoClient.connect(uri);
|
|
6
6
|
client?.topology?.socket?.unref();
|
|
7
7
|
}
|
|
8
8
|
return client;
|
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.10",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "v20"
|
|
@@ -26,16 +26,17 @@
|
|
|
26
26
|
"colors": "^1.4.0",
|
|
27
27
|
"commander": "^12.0.0",
|
|
28
28
|
"console-table-printer": "^2.12.0",
|
|
29
|
-
"mongodb": "^6.
|
|
29
|
+
"mongodb": "^6.5.0",
|
|
30
|
+
"tunnel-ssh": "^5.1.2"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"@types/node": "^20.11.
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
34
|
-
"@typescript-eslint/parser": "^7.
|
|
33
|
+
"@types/node": "^20.11.27",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
|
35
|
+
"@typescript-eslint/parser": "^7.2.0",
|
|
35
36
|
"eslint": "^8.57.0",
|
|
36
37
|
"eslint-plugin-deprecation": "^2.0.0",
|
|
37
38
|
"ts-node": "^10.9.2",
|
|
38
|
-
"typescript": "^5.
|
|
39
|
+
"typescript": "^5.4.2"
|
|
39
40
|
},
|
|
40
41
|
"license": "MIT",
|
|
41
42
|
"scripts": {
|