@dhruv2mars/mdv 0.0.2 → 0.0.3

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/bin/install.js ADDED
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ chmodSync,
4
+ copyFileSync,
5
+ createWriteStream,
6
+ existsSync,
7
+ mkdirSync,
8
+ readFileSync,
9
+ renameSync
10
+ } from 'node:fs';
11
+ import { homedir } from 'node:os';
12
+ import { join } from 'node:path';
13
+ import https from 'node:https';
14
+ import { spawnSync } from 'node:child_process';
15
+ import { fileURLToPath } from 'node:url';
16
+
17
+ const REPO = 'Dhruv2mars/mdv';
18
+
19
+ const installRoot = process.env.MDV_INSTALL_ROOT || join(homedir(), '.mdv');
20
+ const binDir = join(installRoot, 'bin');
21
+ const binName = process.platform === 'win32' ? 'mdv.exe' : 'mdv';
22
+ const dest = join(binDir, binName);
23
+
24
+ if (process.env.MDV_SKIP_DOWNLOAD === '1') process.exit(0);
25
+ if (existsSync(dest)) process.exit(0);
26
+
27
+ mkdirSync(binDir, { recursive: true });
28
+
29
+ const version = pkgVersion();
30
+ const asset = assetName();
31
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${asset}`;
32
+ const tmp = `${dest}.tmp-${Date.now()}`;
33
+
34
+ try {
35
+ console.error(`mdv: download ${asset} v${version}`);
36
+ await download(url, tmp);
37
+ if (process.platform !== 'win32') chmodSync(tmp, 0o755);
38
+ renameSync(tmp, dest);
39
+ process.exit(0);
40
+ } catch (err) {
41
+ try {
42
+ if (existsSync(tmp)) {
43
+ // best-effort cleanup; ignore
44
+ }
45
+ } catch {}
46
+
47
+ console.error(`mdv: download failed (${String(err)})`);
48
+
49
+ if (process.env.MDV_ALLOW_CARGO_FALLBACK === '1') {
50
+ if (cargoInstallFallback()) {
51
+ process.exit(0);
52
+ }
53
+ }
54
+
55
+ console.error('mdv: install incomplete. re-run with MDV_ALLOW_CARGO_FALLBACK=1 or wait for GitHub release assets.');
56
+ process.exit(0);
57
+ }
58
+
59
+ function pkgVersion() {
60
+ try {
61
+ const here = fileURLToPath(new URL('.', import.meta.url));
62
+ const p = readFileSync(join(here, '..', 'package.json'), 'utf8');
63
+ return JSON.parse(p).version;
64
+ } catch {
65
+ return process.env.npm_package_version || '0.0.0';
66
+ }
67
+ }
68
+
69
+ function assetName() {
70
+ const platform = process.platform;
71
+ const arch = process.arch;
72
+ const ext = platform === 'win32' ? '.exe' : '';
73
+ return `mdv-${platform}-${arch}${ext}`;
74
+ }
75
+
76
+ function download(url, outPath) {
77
+ return new Promise((resolve, reject) => {
78
+ const req = https.get(
79
+ url,
80
+ { headers: { 'User-Agent': 'mdv-installer', Accept: 'application/octet-stream' } },
81
+ (res) => {
82
+ if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
83
+ res.resume();
84
+ download(res.headers.location, outPath).then(resolve, reject);
85
+ return;
86
+ }
87
+
88
+ if (res.statusCode !== 200) {
89
+ res.resume();
90
+ reject(new Error(`http ${res.statusCode}`));
91
+ return;
92
+ }
93
+
94
+ const file = createWriteStream(outPath);
95
+ res.pipe(file);
96
+ file.on('finish', () => file.close(resolve));
97
+ file.on('error', reject);
98
+ }
99
+ );
100
+
101
+ req.on('error', reject);
102
+ });
103
+ }
104
+
105
+ function cargoInstallFallback() {
106
+ const probe = spawnSync('cargo', ['--version'], { stdio: 'ignore' });
107
+ if (probe.status !== 0) return false;
108
+
109
+ console.error('mdv: cargo fallback install...');
110
+
111
+ const root = installRoot;
112
+ const install = spawnSync(
113
+ 'cargo',
114
+ [
115
+ 'install',
116
+ 'mdv-cli',
117
+ '--git',
118
+ `https://github.com/${REPO}.git`,
119
+ '--locked',
120
+ '--root',
121
+ root,
122
+ '--config',
123
+ 'net.git-fetch-with-cli=true'
124
+ ],
125
+ { stdio: 'inherit', env: { ...process.env, CARGO_NET_GIT_FETCH_WITH_CLI: 'true' } }
126
+ );
127
+
128
+ if (install.status !== 0) return false;
129
+
130
+ const built = join(root, 'bin', process.platform === 'win32' ? 'mdv-cli.exe' : 'mdv-cli');
131
+ if (!existsSync(built)) return false;
132
+
133
+ try {
134
+ copyFileSync(built, dest);
135
+ if (process.platform !== 'win32') chmodSync(dest, 0o755);
136
+ } catch {
137
+ return false;
138
+ }
139
+
140
+ return true;
141
+ }
package/bin/mdv.js CHANGED
@@ -3,55 +3,29 @@ import { existsSync } from 'node:fs';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
5
  import { spawnSync } from 'node:child_process';
6
+ import { fileURLToPath } from 'node:url';
6
7
 
7
- const REPO = 'https://github.com/Dhruv2mars/mdv.git';
8
8
  const args = process.argv.slice(2);
9
- const envBin = process.env.MDV_BIN;
10
9
 
10
+ const envBin = process.env.MDV_BIN;
11
11
  if (envBin) run(envBin, args);
12
12
 
13
13
  const installRoot = process.env.MDV_INSTALL_ROOT || join(homedir(), '.mdv');
14
- const binName = process.platform === 'win32' ? 'mdv-cli.exe' : 'mdv-cli';
14
+ const binName = process.platform === 'win32' ? 'mdv.exe' : 'mdv';
15
15
  const installedBin = join(installRoot, 'bin', binName);
16
16
 
17
17
  if (!existsSync(installedBin)) {
18
- ensureCargo();
19
- console.error('mdv: installing rust binary (first run)...');
20
- const install = spawnSync(
21
- 'cargo',
22
- [
23
- 'install',
24
- 'mdv-cli',
25
- '--git',
26
- REPO,
27
- '--locked',
28
- '--root',
29
- installRoot,
30
- '--config',
31
- 'net.git-fetch-with-cli=true'
32
- ],
33
- {
34
- stdio: 'inherit',
35
- env: { ...process.env, CARGO_NET_GIT_FETCH_WITH_CLI: 'true' }
36
- }
37
- );
38
-
39
- if (install.status !== 0 || !existsSync(installedBin)) {
40
- console.error('mdv: install failed');
18
+ const here = fileURLToPath(new URL('.', import.meta.url));
19
+ const installer = join(here, 'install.js');
20
+ const res = spawnSync(process.execPath, [installer], { stdio: 'inherit', env: process.env });
21
+ if (res.status !== 0 || !existsSync(installedBin)) {
22
+ console.error('mdv: install missing. try reinstall: npm i -g @dhruv2mars/mdv');
41
23
  process.exit(1);
42
24
  }
43
25
  }
44
26
 
45
27
  run(installedBin, args);
46
28
 
47
- function ensureCargo() {
48
- const probe = spawnSync('cargo', ['--version'], { stdio: 'ignore' });
49
- if (probe.status === 0) return;
50
-
51
- console.error('mdv: rust toolchain not found. install rustup/cargo first.');
52
- process.exit(1);
53
- }
54
-
55
29
  function run(bin, binArgs) {
56
30
  const res = spawnSync(bin, binArgs, { stdio: 'inherit' });
57
31
  process.exit(res.status ?? 1);
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { mkdtempSync, rmSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { spawnSync } from 'node:child_process';
6
+
7
+ const root = mkdtempSync(join(tmpdir(), 'mdv-install-'));
8
+ const env = { ...process.env, MDV_INSTALL_ROOT: root };
9
+
10
+ const res = spawnSync(process.execPath, [new URL('./install.js', import.meta.url).pathname], {
11
+ stdio: 'inherit',
12
+ env
13
+ });
14
+
15
+ rmSync(root, { recursive: true, force: true });
16
+ process.exit(res.status ?? 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhruv2mars/mdv",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Terminal-first markdown visualizer/editor",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,11 @@
10
10
  "bin"
11
11
  ],
12
12
  "scripts": {
13
- "mdv": "node bin/mdv.js"
13
+ "mdv": "node bin/mdv.js",
14
+ "postinstall": "node bin/install.js",
15
+ "selftest": "node bin/selftest.js",
16
+ "lint": "node --check bin/mdv.js && node --check bin/install.js && node --check bin/selftest.js",
17
+ "test": "node scripts/test.js"
14
18
  },
15
19
  "keywords": [
16
20
  "markdown",
@@ -31,5 +35,8 @@
31
35
  "node": ">=18"
32
36
  },
33
37
  "preferGlobal": true,
34
- "license": "MIT"
38
+ "license": "MIT",
39
+ "devDependencies": {
40
+ "@mdv/rust": "workspace:*"
41
+ }
35
42
  }