@dhruv2mars/mdv 0.0.14 → 0.0.16

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/README.md CHANGED
@@ -23,6 +23,7 @@ Manual upgrade:
23
23
  ```bash
24
24
  mdv update
25
25
  ```
26
+ Uses detected install manager (bun/pnpm/yarn/npm), prefers original installer metadata.
26
27
 
27
28
  Stream stdin:
28
29
 
@@ -16,6 +16,22 @@ export function checksumsAssetNameFromBinaryAsset(asset) {
16
16
  return checksumsAssetNameFor(m[1], m[2]);
17
17
  }
18
18
 
19
+ export function packageManagerHintFromEnv(env = process.env) {
20
+ const execPath = String(env.npm_execpath || '').toLowerCase();
21
+ if (execPath.includes('bun')) return 'bun';
22
+ if (execPath.includes('pnpm')) return 'pnpm';
23
+ if (execPath.includes('yarn')) return 'yarn';
24
+ if (execPath.includes('npm')) return 'npm';
25
+
26
+ const ua = String(env.npm_config_user_agent || '').toLowerCase();
27
+ if (ua.startsWith('bun/')) return 'bun';
28
+ if (ua.startsWith('pnpm/')) return 'pnpm';
29
+ if (ua.startsWith('yarn/')) return 'yarn';
30
+ if (ua.startsWith('npm/')) return 'npm';
31
+
32
+ return null;
33
+ }
34
+
19
35
  function parseIntEnv(value, fallback, min, max) {
20
36
  const parsed = Number.parseInt(String(value ?? ''), 10);
21
37
  if (!Number.isFinite(parsed)) return fallback;
package/bin/install.js CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  checksumsAssetNameFor,
25
25
  computeBackoffDelay,
26
26
  installTuningFromEnv,
27
+ packageManagerHintFromEnv,
27
28
  parseChecksumForAsset,
28
29
  resolveReleaseAssetBundle,
29
30
  shouldUseFallbackUrl
@@ -33,6 +34,7 @@ const REPO = 'Dhruv2mars/mdv';
33
34
 
34
35
  const installRoot = process.env.MDV_INSTALL_ROOT || join(homedir(), '.mdv');
35
36
  const binDir = join(installRoot, 'bin');
37
+ const metaPath = join(installRoot, 'install-meta.json');
36
38
  const binName = process.platform === 'win32' ? 'mdv.exe' : 'mdv';
37
39
  const dest = join(binDir, binName);
38
40
  const tuning = installTuningFromEnv(process.env);
@@ -83,6 +85,7 @@ try {
83
85
  persistCache(cachePaths, checksumsText, dest);
84
86
  trace('cache-store');
85
87
  }
88
+ persistInstallMeta();
86
89
  trace('success');
87
90
  process.exit(0);
88
91
  } catch (err) {
@@ -343,6 +346,21 @@ function persistCache(paths, checksumsText, sourceBinaryPath) {
343
346
  }
344
347
  }
345
348
 
349
+ function persistInstallMeta() {
350
+ const packageManager = packageManagerHintFromEnv(process.env);
351
+ const meta = {
352
+ packageManager,
353
+ version,
354
+ savedAt: new Date().toISOString()
355
+ };
356
+ try {
357
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8');
358
+ trace(`meta-store pm=${packageManager || 'unknown'}`);
359
+ } catch {
360
+ trace('meta-store-failed');
361
+ }
362
+ }
363
+
346
364
  function checksumMismatchError(asset, expected, actual) {
347
365
  const err = new Error(
348
366
  buildChecksumMismatchHelp({
package/bin/mdv-lib.js CHANGED
@@ -1,7 +1,11 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
1
2
  import { homedir } from 'node:os';
2
3
  import { join } from 'node:path';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { packageManagerHintFromEnv } from './install-lib.js';
3
6
 
4
7
  const PACKAGE_NAME = '@dhruv2mars/mdv@latest';
8
+ const SUPPORTED_PMS = new Set(['bun', 'pnpm', 'yarn', 'npm']);
5
9
 
6
10
  export function binNameForPlatform(platform = process.platform) {
7
11
  return platform === 'win32' ? 'mdv.exe' : 'mdv';
@@ -21,17 +25,91 @@ export function shouldRunUpdateCommand(args) {
21
25
  return Array.isArray(args) && args.length > 0 && args[0] === 'update';
22
26
  }
23
27
 
28
+ function updateArgsFor(pm) {
29
+ if (pm === 'bun') return ['add', '-g', PACKAGE_NAME];
30
+ if (pm === 'pnpm') return ['add', '-g', PACKAGE_NAME];
31
+ if (pm === 'yarn') return ['global', 'add', PACKAGE_NAME];
32
+ return ['install', '-g', PACKAGE_NAME];
33
+ }
34
+
35
+ function readInstallMeta(installRoot) {
36
+ const path = join(installRoot, 'install-meta.json');
37
+ if (!existsSync(path)) return null;
38
+ try {
39
+ return JSON.parse(readFileSync(path, 'utf8'));
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+
45
+ function isSupportedPm(pm) {
46
+ return typeof pm === 'string' && SUPPORTED_PMS.has(pm);
47
+ }
48
+
49
+ function defaultProbe(command) {
50
+ const args = command === 'bun'
51
+ ? ['pm', 'ls', '-g']
52
+ : command === 'pnpm'
53
+ ? ['list', '-g', '--depth=0']
54
+ : command === 'yarn'
55
+ ? ['global', 'list', '--depth=0']
56
+ : ['list', '-g', '--depth=0'];
57
+
58
+ try {
59
+ const res = spawnSync(command, args, { encoding: 'utf8', stdio: 'pipe' });
60
+ return {
61
+ status: res.status ?? 1,
62
+ stdout: String(res.stdout || '')
63
+ };
64
+ } catch {
65
+ return { status: 1, stdout: '' };
66
+ }
67
+ }
68
+
69
+ function pmSearchOrder(preferred) {
70
+ const base = ['bun', 'pnpm', 'yarn', 'npm'];
71
+ if (!isSupportedPm(preferred)) return base;
72
+ return [preferred, ...base.filter((x) => x !== preferred)];
73
+ }
74
+
75
+ export function detectInstalledPackageManager(probe = defaultProbe, preferred = null) {
76
+ for (const command of pmSearchOrder(preferred)) {
77
+ const out = probe(command);
78
+ if ((out?.status ?? 1) !== 0) continue;
79
+ if (String(out?.stdout || '').includes('@dhruv2mars/mdv')) return command;
80
+ }
81
+ return null;
82
+ }
83
+
24
84
  export function resolveUpdateCommand(env = process.env) {
25
- const npmExecPath = env.npm_execpath;
26
- if (typeof npmExecPath === 'string' && npmExecPath.endsWith('.js')) {
85
+ const installRoot = resolveInstallRoot(env);
86
+ const metaPm = readInstallMeta(installRoot)?.packageManager;
87
+ const envPm = packageManagerHintFromEnv(env);
88
+ const hintPm = isSupportedPm(metaPm) ? metaPm : (isSupportedPm(envPm) ? envPm : null);
89
+ const detectedPm = env === process.env && !hintPm
90
+ ? detectInstalledPackageManager(defaultProbe, null)
91
+ : null;
92
+ const manager = hintPm || detectedPm || 'npm';
93
+
94
+ if (manager === 'npm') {
95
+ const npmExecPath = env.npm_execpath;
96
+ if (typeof npmExecPath === 'string' && npmExecPath.endsWith('.js')) {
97
+ return {
98
+ command: process.execPath,
99
+ args: [npmExecPath, ...updateArgsFor('npm')]
100
+ };
101
+ }
102
+ }
103
+
104
+ if (isSupportedPm(manager)) {
27
105
  return {
28
- command: process.execPath,
29
- args: [npmExecPath, 'install', '-g', PACKAGE_NAME]
106
+ command: manager,
107
+ args: updateArgsFor(manager)
30
108
  };
31
109
  }
32
110
 
33
111
  return {
34
112
  command: 'npm',
35
- args: ['install', '-g', PACKAGE_NAME]
113
+ args: updateArgsFor('npm')
36
114
  };
37
115
  }
package/bin/mdv.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { existsSync } from 'node:fs';
3
3
  import { spawnSync } from 'node:child_process';
4
+ import { join } from 'node:path';
4
5
  import { fileURLToPath } from 'node:url';
5
6
  import {
6
7
  resolveInstalledBin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhruv2mars/mdv",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Terminal-first markdown visualizer/editor",
5
5
  "type": "module",
6
6
  "bin": {