@wwkit/opm 1.0.14 → 1.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.
@@ -18,6 +18,9 @@ import { getActiveProxy, getActiveRegistry, getConfig } from '../../config.js'
18
18
 
19
19
  const shell = new Shell()
20
20
 
21
+ // 跨平台 null device(curl -o 丢弃输出体)
22
+ const NULL_DEV = process.platform === 'win32' ? 'NUL' : '/dev/null'
23
+
21
24
  /**
22
25
  * 从 URL 或 deb 行中提取主机名和端口(用于 ping 目标)
23
26
  * @param {string} url
@@ -47,8 +50,9 @@ function isUrl(addr) {
47
50
  }
48
51
 
49
52
  // HTTP 状态码 → 可达性判断:2xx/3xx 视为可达,allowlist 中的状态码
50
- // 虽非成功响应但证明服务器已响应(如 404 表示主机/代理存活)
51
- const REACHABLE_ALLOWLIST = [404]
53
+ // 虽非成功响应但证明服务器已响应(如 404 表示主机/代理存活,
54
+ // 429 表示临时限流,服务器实际存活)
55
+ const REACHABLE_ALLOWLIST = [404, 429]
52
56
 
53
57
  function httpReachable(httpCode) {
54
58
  return (httpCode >= 200 && httpCode < 400) || REACHABLE_ALLOWLIST.includes(httpCode)
@@ -85,7 +89,16 @@ function checkByPing(host, count) {
85
89
  ? ['-n', String(count), '-w', '2000', host]
86
90
  : ['-c', String(count), '-W', '2', host]
87
91
 
88
- const child = spawn('ping', args, { stdio: ['pipe', 'pipe', 'pipe'] })
92
+ let child
93
+ try {
94
+ child = spawn('ping', args, { stdio: ['pipe', 'pipe', 'pipe'], shell: true })
95
+ } catch {
96
+ resolve({
97
+ reachable: false, sent: count, received: 0, loss: count,
98
+ lossPercent: 100, rttMin: '', rttAvg: '', rttMax: '', raw: 'ping command failed to execute',
99
+ })
100
+ return
101
+ }
89
102
  let stdout = ''
90
103
  let stderr = ''
91
104
  child.stdout.on('data', (d) => { stdout += d })
@@ -154,10 +167,19 @@ function checkByPing(host, count) {
154
167
  */
155
168
  function checkByCurl(url, proxy) {
156
169
  return new Promise((resolve) => {
157
- const args = ['-k', '-L', '-s', '-o', '/dev/null', '-w', '%{http_code} %{time_total}', '--connect-timeout', '2', '--max-time', '5']
170
+ const args = ['-k', '-L', '-s', '-o', NULL_DEV, '-w', '%{http_code} %{time_total}', '--connect-timeout', '2', '--max-time', '5']
158
171
  if (proxy) args.push('-x', proxy)
159
172
  args.push(url)
160
- const child = spawn('curl', args, { stdio: ['pipe', 'pipe', 'pipe'] })
173
+ let child
174
+ try {
175
+ child = spawn('curl', args, { stdio: ['pipe', 'pipe', 'pipe'], shell: true })
176
+ } catch {
177
+ resolve({
178
+ reachable: false, sent: 1, received: 0, loss: 1,
179
+ lossPercent: 100, rttMin: '', rttAvg: '', rttMax: '', raw: 'curl failed to execute',
180
+ })
181
+ return
182
+ }
161
183
  let stdout = ''
162
184
  let stderr = ''
163
185
  child.stdout.on('data', (d) => { stdout += d })
@@ -204,7 +226,16 @@ function checkByWget(url, proxy) {
204
226
  args.push('-e', `use_proxy=yes`, '-e', `https_proxy=${proxy}`, '-e', `http_proxy=${proxy}`)
205
227
  }
206
228
  args.push(url)
207
- const child = spawn('wget', args, { stdio: ['pipe', 'pipe', 'pipe'] })
229
+ let child
230
+ try {
231
+ child = spawn('wget', args, { stdio: ['pipe', 'pipe', 'pipe'], shell: true })
232
+ } catch {
233
+ resolve({
234
+ reachable: false, sent: 1, received: 0, loss: 1,
235
+ lossPercent: 100, rttMin: '', rttAvg: '', rttMax: '', raw: 'wget failed to execute',
236
+ })
237
+ return
238
+ }
208
239
  let stdout = ''
209
240
  let stderr = ''
210
241
  child.stdout.on('data', (d) => { stdout += d })
@@ -271,7 +302,7 @@ async function checkReachability(address, tool, count, proxy) {
271
302
  return { reachable: false, sent: 0, received: 0, loss: 0, lossPercent: 0, rttMin: '', rttAvg: '', rttMax: '', raw: 'No tool available' }
272
303
  }
273
304
 
274
- export { checkReachability, extractHostPort }
305
+ export { checkReachability, extractHostPort, httpReachable }
275
306
 
276
307
  export class PingGroup {
277
308
  constructor() {
@@ -298,12 +329,9 @@ export class PingGroup {
298
329
  const n = (isNaN(count) || count < 1) ? 4 : count
299
330
  const detail = !!(parsed.flags.d || parsed.flags.detail)
300
331
 
301
- let proxy = ''
302
- if ('p' in parsed.flags || 'proxy' in parsed.flags) {
303
- let raw = parsed.flags.proxy || parsed.flags.p || ''
304
- if (raw === 'true') raw = ''
305
- proxy = raw || getActiveProxy()
306
- }
332
+ let proxy = parsed.flags.proxy || parsed.flags.p || ''
333
+ if (proxy === 'true') proxy = ''
334
+ if (!proxy) proxy = getActiveProxy()
307
335
 
308
336
  if (target === 'proxy') {
309
337
  return this._pingProxy(n, detail, tool)
@@ -318,7 +346,8 @@ export class PingGroup {
318
346
  }
319
347
 
320
348
  if (proxy) {
321
- const usable = await this._checkProxyUsable(proxy, tool, n)
349
+ const testUrl = isUrl(target) ? target : undefined
350
+ const usable = await this._checkProxyUsable(proxy, tool, n, testUrl)
322
351
  if (!usable.ok) {
323
352
  console.error(`[opm] Proxy not usable: ${usable.reason}`)
324
353
  process.exit(1)
@@ -331,12 +360,16 @@ export class PingGroup {
331
360
  }
332
361
 
333
362
  /**
334
- * 检查代理是否可用:通过代理访问 npm active registry 测试
363
+ * 检查代理是否可用:通过代理访问指定 URL 测试
364
+ * @param {string} proxyUrl - 代理地址
365
+ * @param {string} tool - 检测工具
366
+ * @param {number} count - ping 包数量
367
+ * @param {string} [testUrl] - 测试 URL(默认 npm active registry)
335
368
  * @returns {{ ok: boolean, reason: string }}
336
369
  */
337
- async _checkProxyUsable(proxyUrl, tool, count) {
338
- const testUrl = getActiveRegistry('npm')
339
- const result = await checkReachability(testUrl, tool, count, proxyUrl)
370
+ async _checkProxyUsable(proxyUrl, tool, count, testUrl) {
371
+ const url = testUrl || getActiveRegistry('npm')
372
+ const result = await checkReachability(url, tool, count, proxyUrl)
340
373
  if (result.proxyAuthRequired) {
341
374
  return { ok: false, reason: 'authentication required (HTTP 407)' }
342
375
  }
@@ -376,7 +409,13 @@ export class PingGroup {
376
409
  const tools = getRegistryTools()
377
410
 
378
411
  if (proxy) {
379
- const usable = await this._checkProxyUsable(proxy, tool, 1)
412
+ // 用首个可用 registry URL 作为代理可用性测试目标(而非硬编码 npm)
413
+ let testUrl = ''
414
+ for (const t of tools) {
415
+ const u = getActiveRegistry(t)
416
+ if (u) { testUrl = u; break }
417
+ }
418
+ const usable = await this._checkProxyUsable(proxy, tool, 1, testUrl)
380
419
  if (!usable.ok) {
381
420
  console.error(`[opm] Proxy not usable: ${usable.reason}`)
382
421
  process.exit(1)
@@ -459,7 +498,8 @@ Actions:
459
498
 
460
499
  Options:
461
500
  -c, --count <n> Number of packets to send (ping only; default: 4)
462
- -p, --proxy <url> Record proxy used for the check (informational)
501
+ -p, --proxy <url> Proxy address for the check (overrides config proxy.active;
502
+ routes curl/wget requests through the proxy and pre-validates usability)
463
503
  -d, --detail Output full JSON details (default: compact [{tool, address, proxy, reachable}])
464
504
  -h, --help Show this help
465
505
 
package/src/cli/index.js CHANGED
@@ -21,6 +21,7 @@ import { EnsureGroup } from './groups/ensure.js'
21
21
  import { PingGroup } from './groups/ping.js'
22
22
  import { ProcGroup } from './groups/proc.js'
23
23
  import { OverlayGroup } from './groups/overlay.js'
24
+ import { EnvGroup } from './groups/env.js'
24
25
  import { FtpGroup } from '../tools/ftp/index.js'
25
26
  import { GitGroup } from '../tools/git/index.js'
26
27
  import { ShareGroup } from '../tools/share/index.js'
@@ -66,6 +67,7 @@ const GROUPS = {
66
67
  ping: new PingGroup(),
67
68
  proc: new ProcGroup(),
68
69
  overlay: new OverlayGroup(),
70
+ env: new EnvGroup(),
69
71
  }
70
72
 
71
73
  class CLI {
@@ -130,7 +132,7 @@ ${groupLines}
130
132
 
131
133
  Options:
132
134
  -g, --global Global operation (npm: global node_modules; pip: system Python)
133
- -p, --proxy <url> Proxy address (search/info/versions/outdated/install/upgrade)
135
+ -p, --proxy <url> Proxy address (search/info/versions/install/upgrade)
134
136
  -h, --help Show help
135
137
 
136
138
  Run "opm <command> help" for command details.
package/src/index.js CHANGED
@@ -23,6 +23,7 @@ export { DockerGroup } from './cli/groups/docker.js'
23
23
  export { PingGroup } from './cli/groups/ping.js'
24
24
  export { ProcGroup } from './cli/groups/proc.js'
25
25
  export { OverlayGroup } from './cli/groups/overlay.js'
26
+ export { EnvGroup, parseEnvBlocks, parseRegOutput, isValidEnvKey } from './cli/groups/env.js'
26
27
  export { FtpGroup } from './tools/ftp/index.js'
27
28
  export { GitGroup } from './tools/git/index.js'
28
29
  export { ShareGroup } from './tools/share/index.js'
@@ -62,7 +63,7 @@ export {
62
63
  } from './presets.js'
63
64
  export { PROXY_PRESETS } from './proxy-presets.js'
64
65
  export { output } from './formatter.js'
65
- export { downloadToFile, fetchText } from './managers/http.js'
66
+ export { downloadToFile, fetchText } from '@wwkit/shared'
66
67
  export {
67
68
  getConfig, getSection, copyBuiltinConfig, getActiveRegistry, setActiveRegistry,
68
69
  getUserConfigDir, getUserConfigFile, getActiveProxy,
@@ -326,23 +326,6 @@ export class AptManager extends PackageManager {
326
326
  return { name, versions, registry }
327
327
  }
328
328
 
329
- async listOutdated(opts = {}) {
330
- const out = this._exec(['list', '--upgradable', ...this._proxyArgs(opts.proxy)], { allowNonZero: true })
331
- const items = []
332
- for (const line of this._parseLines(out)) {
333
- const m = line.match(/^(\S+?)\/(\S+)\s+(\S+)\s+(\S+)\s+\[(.*?)\]$/)
334
- if (m) {
335
- const from = m[5].match(/upgradable from:\s*(\S+)/)
336
- items.push({
337
- name: m[1],
338
- current: from ? from[1] : '',
339
- latest: m[3]
340
- })
341
- }
342
- }
343
- return items
344
- }
345
-
346
329
  async install(name, version, opts = {}) {
347
330
  const spec = version ? `${name}=${version}` : name
348
331
  const args = ['get', 'install', '-y', spec, ...this._proxyArgs(opts.proxy)]
@@ -30,12 +30,6 @@
30
30
  * @typedef {Object} InstalledItem
31
31
  * @property {string} name - 包名
32
32
  * @property {string} version - 版本
33
- *
34
- * @typedef {Object} OutdatedItem
35
- * @property {string} name - 包名
36
- * @property {string} current - 当前版本
37
- * @property {string} [wanted] - 期望版本
38
- * @property {string} latest - 最新版本
39
33
  */
40
34
  export class PackageManager {
41
35
  constructor() {
@@ -132,15 +126,6 @@ export class PackageManager {
132
126
  throw new Error(`${this.name}: listInstalled not implemented`)
133
127
  }
134
128
 
135
- /**
136
- * 列出过期包
137
- * @param {{ global?: boolean, proxy?: string }} [opts] - 选项
138
- * @returns {Promise<OutdatedItem[]>}
139
- */
140
- async listOutdated(opts) {
141
- throw new Error(`${this.name}: listOutdated not implemented`)
142
- }
143
-
144
129
  /**
145
130
  * 安装包
146
131
  * @param {string} name - 包名
@@ -166,6 +166,7 @@ export class BrewManager extends PackageManager {
166
166
  _execInherit(args, opts = {}) {
167
167
  const result = spawnSync(this._brewBin(), args, {
168
168
  stdio: 'inherit',
169
+ shell: true,
169
170
  env: this._buildEnv(opts.proxy),
170
171
  })
171
172
  if (result.error) {
@@ -213,33 +214,6 @@ export class BrewManager extends PackageManager {
213
214
  return items
214
215
  }
215
216
 
216
- /**
217
- * 解析 brew outdated --json=v2 输出为过期项数组(formulae + casks)
218
- * @param {string} text
219
- * @returns {{ name: string, current: string, latest: string }[]}
220
- * @private
221
- */
222
- _parseOutdatedJson(text) {
223
- let data
224
- try {
225
- data = JSON.parse(text)
226
- } catch {
227
- return []
228
- }
229
- const items = []
230
- for (const group of ['formulae', 'casks']) {
231
- const list = Array.isArray(data[group]) ? data[group] : []
232
- for (const item of list) {
233
- items.push({
234
- name: item.name,
235
- current: (Array.isArray(item.installed_versions) ? item.installed_versions : []).join(', '),
236
- latest: item.current_version || '',
237
- })
238
- }
239
- }
240
- return items
241
- }
242
-
243
217
  async getVersion() {
244
218
  try {
245
219
  const out = this._exec(['--version'], { allowNonZero: true })
@@ -340,11 +314,6 @@ export class BrewManager extends PackageManager {
340
314
  return { name, versions, registry }
341
315
  }
342
316
 
343
- async listOutdated(opts = {}) {
344
- const out = this._exec(['outdated', '--json=v2'], { allowNonZero: true, proxy: opts.proxy })
345
- return this._parseOutdatedJson(out)
346
- }
347
-
348
317
  async install(name, version, opts = {}) {
349
318
  if (!isHomebrewInstalled()) {
350
319
  console.log('[opm] Homebrew not installed, auto-installing...')
@@ -2,7 +2,7 @@
2
2
  * bun 包管理器实现
3
3
  *
4
4
  * Bun 是全栈 JS 工具链(runtime + 包管理器 + 打包器)。
5
- * 包管理命令通过 bun CLI 实现,源查询通过 HTTP 直接查 npm registry。
5
+ * 包管理命令通过 bun CLI 实现,源查询通过共享 fetchText 查 npm registry。
6
6
  * 镜像通过 BUN_CONFIG_REGISTRY 环境变量传递给 bun 命令。
7
7
  */
8
8
 
@@ -11,6 +11,7 @@ import fs from 'node:fs'
11
11
  import os from 'node:os'
12
12
  import path from 'node:path'
13
13
  import { PackageManager } from './base.js'
14
+ import { fetchText } from '@wwkit/shared'
14
15
  import { getActiveRegistry, setActiveRegistry } from '../config.js'
15
16
 
16
17
  export class BunManager extends PackageManager {
@@ -108,52 +109,24 @@ export class BunManager extends PackageManager {
108
109
 
109
110
  /**
110
111
  * 通过 HTTP 查询 npm registry 获取包元数据
112
+ * 使用共享 fetchText(支持 HTTP/SOCKS5 代理隧道,与 pip/composer 一致)
111
113
  * @param {string} pkgName
112
114
  * @param {{ proxy?: string }} [opts]
113
115
  * @returns {Promise<object|null>}
114
116
  * @private
115
117
  */
116
118
  async _fetchRegistryMetadata(pkgName, opts = {}) {
117
- const registry = getActiveRegistry('bun').replace(/\/$/, '')
119
+ const registry = (getActiveRegistry('bun') || 'https://registry.npmjs.org').replace(/\/$/, '')
118
120
  const url = `${registry}/${encodeURIComponent(pkgName).replace('%40', '@')}`
119
121
  try {
120
- const { default: http } = await import('node:http')
121
- const { default: https } = await import('node:https')
122
- const client = url.startsWith('https') ? https : http
123
- const proxyAgent = opts.proxy ? await this._getProxyAgent(opts.proxy) : null
124
- return new Promise((resolve) => {
125
- const req = client.get(url, { agent: proxyAgent }, (res) => {
126
- let data = ''
127
- res.on('data', (chunk) => (data += chunk))
128
- res.on('end', () => {
129
- try {
130
- resolve(JSON.parse(data))
131
- } catch {
132
- resolve(null)
133
- }
134
- })
135
- })
136
- req.on('error', () => resolve(null))
137
- req.setTimeout(15000, () => {
138
- req.destroy()
139
- resolve(null)
140
- })
141
- })
122
+ const text = await fetchText(url, { proxy: opts.proxy })
123
+ if (!text) return null
124
+ return JSON.parse(text)
142
125
  } catch {
143
126
  return null
144
127
  }
145
128
  }
146
129
 
147
- /**
148
- * 获取 proxy agent(简化实现,仅支持 http proxy)
149
- * @param {string} proxy
150
- * @returns {Promise<undefined>}
151
- * @private
152
- */
153
- async _getProxyAgent(proxy) {
154
- return undefined
155
- }
156
-
157
130
  async getVersion() {
158
131
  try {
159
132
  const version = this._exec(['--version'], { allowNonZero: true }).trim()
@@ -269,30 +242,6 @@ export class BunManager extends PackageManager {
269
242
  return { name, versions, registry }
270
243
  }
271
244
 
272
- async listOutdated(opts = {}) {
273
- const args = ['outdated']
274
- if (opts.global) args.push('-g')
275
- try {
276
- const out = this._exec(args, { allowNonZero: true, proxy: opts.proxy })
277
- const items = []
278
- const lines = out.split('\n')
279
- for (const line of lines) {
280
- const parts = line.trim().split(/\s+/)
281
- if (parts.length >= 3 && parts[0] !== 'package' && parts[0] !== 'name') {
282
- items.push({
283
- name: parts[0],
284
- current: parts[1] || 'unknown',
285
- wanted: parts[1] || '',
286
- latest: parts[2] || 'unknown',
287
- })
288
- }
289
- }
290
- return items
291
- } catch {
292
- return []
293
- }
294
- }
295
-
296
245
  async install(name, version, opts = {}) {
297
246
  const spec = version ? `${name}@${version}` : name
298
247
  const args = ['add', spec]
@@ -14,7 +14,7 @@ import fs from 'node:fs'
14
14
  import os from 'node:os'
15
15
  import path from 'node:path'
16
16
  import { PackageManager } from './base.js'
17
- import { fetchText } from './http.js'
17
+ import { fetchText } from '@wwkit/shared'
18
18
  import { getActiveRegistry, setActiveRegistry } from '../config.js'
19
19
 
20
20
  export class ComposerManager extends PackageManager {
@@ -298,21 +298,6 @@ export class ComposerManager extends PackageManager {
298
298
  return { name, versions, registry }
299
299
  }
300
300
 
301
- async listOutdated(opts = {}) {
302
- const out = this._exec(['outdated', '--format=json'], { allowNonZero: true, proxy: opts.proxy })
303
- try {
304
- const data = JSON.parse(out)
305
- const installed = Array.isArray(data.installed) ? data.installed : []
306
- return installed.map((item) => ({
307
- name: item.name,
308
- current: item.version || '',
309
- latest: item.latest || '',
310
- }))
311
- } catch {
312
- return []
313
- }
314
- }
315
-
316
301
  async install(name, version, opts = {}) {
317
302
  const spec = version ? `${name}:${version}` : name
318
303
  this._execInherit(['require', spec, '--no-interaction'], { proxy: opts.proxy })
@@ -319,23 +319,6 @@ export class DnfManager extends PackageManager {
319
319
  return { name, versions, registry }
320
320
  }
321
321
 
322
- async listOutdated(opts = {}) {
323
- const args = ['list', '--upgrades', ...this._proxyArgs(opts.proxy)]
324
- const out = this._exec(args, { allowNonZero: true })
325
- const items = []
326
- for (const line of this._parseLines(out)) {
327
- const parts = line.split(/\s+/)
328
- if (parts.length >= 3 && parts[1].includes('-')) {
329
- items.push({
330
- name: parts[0].replace(ARCH_SUFFIX, ''),
331
- current: parts[1],
332
- latest: parts[2]
333
- })
334
- }
335
- }
336
- return items
337
- }
338
-
339
322
  async install(name, version, opts = {}) {
340
323
  const spec = version ? `${name}-${version}` : name
341
324
  const args = ['install', '-y', spec, ...this._proxyArgs(opts.proxy)]
@@ -422,26 +422,6 @@ export class NpmManager extends PackageManager {
422
422
  return { name, versions: [], registry }
423
423
  }
424
424
 
425
- async listOutdated(opts = {}) {
426
- try {
427
- const args = ['outdated']
428
- if (opts.global) args.push('-g')
429
- args.push(...this._proxyArgs(opts.proxy))
430
- args.push(...this._registryArgs())
431
- const data = this._execJson(args)
432
- if (!data) return []
433
- const items = Object.entries(data).map(([name, info]) => ({
434
- name,
435
- current: info.current || 'missing',
436
- wanted: info.wanted || '',
437
- latest: info.latest || ''
438
- }))
439
- return items
440
- } catch (err) {
441
- throw new Error(`npm outdated failed: ${err.message}`)
442
- }
443
- }
444
-
445
425
  /**
446
426
  * 查询 npm 主版本号(缓存),用于判断是否支持 --allow-scripts(npm >= 11)
447
427
  * @returns {number}
@@ -9,7 +9,7 @@ import { execSync, spawnSync } from 'node:child_process'
9
9
  import path from 'node:path'
10
10
  import { URL } from 'node:url'
11
11
  import { PackageManager } from './base.js'
12
- import { fetchText } from './http.js'
12
+ import { fetchText } from '@wwkit/shared'
13
13
  import { getActiveRegistry, setActiveRegistry } from '../config.js'
14
14
 
15
15
  export class PipManager extends PackageManager {
@@ -511,27 +511,6 @@ export class PipManager extends PackageManager {
511
511
  return { name, versions: [], registry }
512
512
  }
513
513
 
514
- async listOutdated(opts = {}) {
515
- try {
516
- const args = ['list', '--outdated', '--format=json']
517
- if (opts.proxy) args.push('--proxy', opts.proxy)
518
- const jsonOut = this._execPip(args, { ...opts, allowNonZero: true })
519
- const parsed = JSON.parse(jsonOut)
520
- if (!Array.isArray(parsed)) return []
521
- return parsed.map((item) => ({
522
- name: item.name || '',
523
- current: item.version || '',
524
- latest: item.latest_version || '',
525
- ...(opts.global ? { global: true } : {})
526
- }))
527
- } catch (err) {
528
- if (err.message.includes('No packages') || err.message.includes('No broken')) {
529
- return []
530
- }
531
- throw new Error(`pip list --outdated failed: ${err.message}`)
532
- }
533
- }
534
-
535
514
  async install(name, version, opts = {}) {
536
515
  const spec = version ? `${name}==${version}` : name
537
516
  const args = ['install', spec]
@@ -52,7 +52,13 @@ export async function getPortMap() {
52
52
  const args = shell.isWindows ? ['-ano'] : ['-tlnp']
53
53
 
54
54
  return new Promise((resolve) => {
55
- const child = spawn(fallback, args, { stdio: ['pipe', 'pipe', 'pipe'] })
55
+ let child
56
+ try {
57
+ child = spawn(fallback, args, { stdio: ['pipe', 'pipe', 'pipe'], shell: true })
58
+ } catch {
59
+ resolve(map)
60
+ return
61
+ }
56
62
  let stdout = ''
57
63
  child.stdout.on('data', (d) => { stdout += d })
58
64
  child.on('close', () => {
@@ -237,10 +237,6 @@ export class RuntimeManager extends PackageManager {
237
237
  return this._parseInstalled(out)
238
238
  }
239
239
 
240
- async listOutdated(opts = {}) {
241
- return []
242
- }
243
-
244
240
  async install(name, version, opts = {}) {
245
241
  if (!version) {
246
242
  throw new Error(this.cfg.installUsage)
@@ -221,20 +221,6 @@ export class WingetManager extends PackageManager {
221
221
  }
222
222
  }
223
223
 
224
- async listOutdated(opts = {}) {
225
- const out = this._exec(
226
- ['list', '--upgrade-available', '--accept-source-agreements', '--disable-interactivity'],
227
- { allowNonZero: true }
228
- )
229
- return this._parseTable(out).map((r) => ({
230
- name: r.Name || r.Id,
231
- id: r.Id,
232
- current: r.Version || '',
233
- latest: r.Available || '',
234
- source: r.Source || '',
235
- }))
236
- }
237
-
238
224
  async install(name, version, opts = {}) {
239
225
  const args = ['install', name, '--accept-package-agreements', '--accept-source-agreements']
240
226
  if (version) args.push('--version', version)