Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ dist
packages/node-modules-inspector/src/app/public/fonts
packages/node-modules-inspector/runtime
.vite-inspect
.pnp*
.yarn
14 changes: 14 additions & 0 deletions fixtures/yarn/dev.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable antfu/no-top-level-await */
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { x } from 'tinyexec'

process.env.NMI_CWD = process.cwd()

await x('pnpm', ['run', 'dev'], {
nodeOptions: {
cwd: fileURLToPath(new URL('../../packages/node-modules-inspector', import.meta.url)),
stdio: 'inherit',
env: process.env,
},
})
13 changes: 13 additions & 0 deletions fixtures/yarn/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "module",
"packageManager": "yarn@4.7.0",
"scripts": {
"dev": "node dev.mjs"
},
"dependencies": {
"vite-plugin-inspect": "^11.0.0"
},
"devDependencies": {
"tinyexec": "^0.3.2"
}
}
256 changes: 256 additions & 0 deletions fixtures/yarn/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!

__metadata:
version: 8
cacheKey: 10c0

"@polka/url@npm:^1.0.0-next.24":
version: 1.0.0-next.28
resolution: "@polka/url@npm:1.0.0-next.28"
checksum: 10c0/acc5ea62597e4da2fb42dbee02749d07f102ae7d6d2c966bf7e423c79cd65d1621da305af567e6e7c232f3b565e242d1ec932cbb3dcc0db1508d02e9a2cafa2e
languageName: node
linkType: hard

"ansis@npm:^3.16.0":
version: 3.17.0
resolution: "ansis@npm:3.17.0"
checksum: 10c0/d8fa94ca7bb91e7e5f8a7d323756aa075facce07c5d02ca883673e128b2873d16f93e0dec782f98f1eeb1f2b3b4b7b60dcf0ad98fb442e75054fe857988cc5cb
languageName: node
linkType: hard

"birpc@npm:^2.0.19":
version: 2.2.0
resolution: "birpc@npm:2.2.0"
checksum: 10c0/7866197d0dd2f65473161d1959ad543f0903a6ead480605ce0f1138ced28389821d80c54627722462181c18b62fe60297166658cc80d9836e192a1df84c51077
languageName: node
linkType: hard

"bundle-name@npm:^4.1.0":
version: 4.1.0
resolution: "bundle-name@npm:4.1.0"
dependencies:
run-applescript: "npm:^7.0.0"
checksum: 10c0/8e575981e79c2bcf14d8b1c027a3775c095d362d1382312f444a7c861b0e21513c0bd8db5bd2b16e50ba0709fa622d4eab6b53192d222120305e68359daece29
languageName: node
linkType: hard

"debug@npm:^4.4.0":
version: 4.4.0
resolution: "debug@npm:4.4.0"
dependencies:
ms: "npm:^2.1.3"
peerDependenciesMeta:
supports-color:
optional: true
checksum: 10c0/db94f1a182bf886f57b4755f85b3a74c39b5114b9377b7ab375dc2cfa3454f09490cc6c30f829df3fc8042bc8b8995f6567ce5cd96f3bc3688bd24027197d9de
languageName: node
linkType: hard

"default-browser-id@npm:^5.0.0":
version: 5.0.0
resolution: "default-browser-id@npm:5.0.0"
checksum: 10c0/957fb886502594c8e645e812dfe93dba30ed82e8460d20ce39c53c5b0f3e2afb6ceaec2249083b90bdfbb4cb0f34e1f73fde3d68cac00becdbcfd894156b5ead
languageName: node
linkType: hard

"default-browser@npm:^5.2.1":
version: 5.2.1
resolution: "default-browser@npm:5.2.1"
dependencies:
bundle-name: "npm:^4.1.0"
default-browser-id: "npm:^5.0.0"
checksum: 10c0/73f17dc3c58026c55bb5538749597db31f9561c0193cd98604144b704a981c95a466f8ecc3c2db63d8bfd04fb0d426904834cfc91ae510c6aeb97e13c5167c4d
languageName: node
linkType: hard

"define-lazy-prop@npm:^3.0.0":
version: 3.0.0
resolution: "define-lazy-prop@npm:3.0.0"
checksum: 10c0/5ab0b2bf3fa58b3a443140bbd4cd3db1f91b985cc8a246d330b9ac3fc0b6a325a6d82bddc0b055123d745b3f9931afeea74a5ec545439a1630b9c8512b0eeb49
languageName: node
linkType: hard

"error-stack-parser-es@npm:^1.0.5":
version: 1.0.5
resolution: "error-stack-parser-es@npm:1.0.5"
checksum: 10c0/040665eb87a42fe068c0da501bc258f3d15d3a03963c0723d7a2741e251d400c9776a52d2803afdc5709def99554cdb5a5d99c203c7eaf4885d3fbc217e2e8f7
languageName: node
linkType: hard

"is-docker@npm:^3.0.0":
version: 3.0.0
resolution: "is-docker@npm:3.0.0"
bin:
is-docker: cli.js
checksum: 10c0/d2c4f8e6d3e34df75a5defd44991b6068afad4835bb783b902fa12d13ebdb8f41b2a199dcb0b5ed2cb78bfee9e4c0bbdb69c2d9646f4106464674d3e697a5856
languageName: node
linkType: hard

"is-inside-container@npm:^1.0.0":
version: 1.0.0
resolution: "is-inside-container@npm:1.0.0"
dependencies:
is-docker: "npm:^3.0.0"
bin:
is-inside-container: cli.js
checksum: 10c0/a8efb0e84f6197e6ff5c64c52890fa9acb49b7b74fed4da7c95383965da6f0fa592b4dbd5e38a79f87fc108196937acdbcd758fcefc9b140e479b39ce1fcd1cd
languageName: node
linkType: hard

"is-wsl@npm:^3.1.0":
version: 3.1.0
resolution: "is-wsl@npm:3.1.0"
dependencies:
is-inside-container: "npm:^1.0.0"
checksum: 10c0/d3317c11995690a32c362100225e22ba793678fe8732660c6de511ae71a0ff05b06980cf21f98a6bf40d7be0e9e9506f859abe00a1118287d63e53d0a3d06947
languageName: node
linkType: hard

"mrmime@npm:^2.0.0":
version: 2.0.1
resolution: "mrmime@npm:2.0.1"
checksum: 10c0/af05afd95af202fdd620422f976ad67dc18e6ee29beb03dd1ce950ea6ef664de378e44197246df4c7cdd73d47f2e7143a6e26e473084b9e4aa2095c0ad1e1761
languageName: node
linkType: hard

"ms@npm:^2.1.3":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
languageName: node
linkType: hard

"ohash@npm:^2.0.4":
version: 2.0.9
resolution: "ohash@npm:2.0.9"
checksum: 10c0/05914081708aebe54314dd40b64ba23cee1f19f1011c24a3b6168a55965181571cd8e9c6314911088411150f81ac97916c06d011d0130b85e4339d490547fdd4
languageName: node
linkType: hard

"open@npm:^10.1.0":
version: 10.1.0
resolution: "open@npm:10.1.0"
dependencies:
default-browser: "npm:^5.2.1"
define-lazy-prop: "npm:^3.0.0"
is-inside-container: "npm:^1.0.0"
is-wsl: "npm:^3.1.0"
checksum: 10c0/c86d0b94503d5f735f674158d5c5d339c25ec2927562f00ee74590727292ed23e1b8d9336cb41ffa7e1fa4d3641d29b199b4ea37c78cb557d72b511743e90ebb
languageName: node
linkType: hard

"pathe@npm:^2.0.2":
version: 2.0.3
resolution: "pathe@npm:2.0.3"
checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1
languageName: node
linkType: hard

"perfect-debounce@npm:^1.0.0":
version: 1.0.0
resolution: "perfect-debounce@npm:1.0.0"
checksum: 10c0/e2baac416cae046ef1b270812cf9ccfb0f91c04ea36ac7f5b00bc84cb7f41bdbba087c0ab21b4e02a7ef3a1f1f6db399f137cecec46868bd7d8d88c2a9ee431f
languageName: node
linkType: hard

"picomatch@npm:^4.0.2":
version: 4.0.2
resolution: "picomatch@npm:4.0.2"
checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc
languageName: node
linkType: hard

"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
tinyexec: "npm:^0.3.2"
vite-plugin-inspect: "npm:^11.0.0"
languageName: unknown
linkType: soft

"run-applescript@npm:^7.0.0":
version: 7.0.0
resolution: "run-applescript@npm:7.0.0"
checksum: 10c0/bd821bbf154b8e6c8ecffeaf0c33cebbb78eb2987476c3f6b420d67ab4c5301faa905dec99ded76ebb3a7042b4e440189ae6d85bbbd3fc6e8d493347ecda8bfe
languageName: node
linkType: hard

"sirv@npm:^3.0.1":
version: 3.0.1
resolution: "sirv@npm:3.0.1"
dependencies:
"@polka/url": "npm:^1.0.0-next.24"
mrmime: "npm:^2.0.0"
totalist: "npm:^3.0.0"
checksum: 10c0/7cf64b28daa69b15f77b38b0efdd02c007b72bb3ec5f107b208ebf59f01b174ef63a1db3aca16d2df925501831f4c209be6ece3302b98765919ef5088b45bf80
languageName: node
linkType: hard

"tinyexec@npm:^0.3.2":
version: 0.3.2
resolution: "tinyexec@npm:0.3.2"
checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90
languageName: node
linkType: hard

"totalist@npm:^3.0.0":
version: 3.0.1
resolution: "totalist@npm:3.0.1"
checksum: 10c0/4bb1fadb69c3edbef91c73ebef9d25b33bbf69afe1e37ce544d5f7d13854cda15e47132f3e0dc4cafe300ddb8578c77c50a65004d8b6e97e77934a69aa924863
languageName: node
linkType: hard

"unplugin-utils@npm:^0.2.0":
version: 0.2.4
resolution: "unplugin-utils@npm:0.2.4"
dependencies:
pathe: "npm:^2.0.2"
picomatch: "npm:^4.0.2"
checksum: 10c0/b5ab2db37823f5b4c8ee8719caa4b5a50b2da33c74c8110d46deb7a2399dfa15cbcaa0cff62aa6400c76e778e42becd9195c09b6502c0c007d03610f432c875f
languageName: node
linkType: hard

"vite-dev-rpc@npm:^1.0.7":
version: 1.0.7
resolution: "vite-dev-rpc@npm:1.0.7"
dependencies:
birpc: "npm:^2.0.19"
vite-hot-client: "npm:^2.0.4"
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1
checksum: 10c0/e20675c17316d3a20f3b190da50e2d52cc5c15fc5b67fead41c3f914ecb6c266fab16a198e11e53ca043321425230ea4b4db1aacb6e4616fce7ff974e0b16477
languageName: node
linkType: hard

"vite-hot-client@npm:^2.0.4":
version: 2.0.4
resolution: "vite-hot-client@npm:2.0.4"
peerDependencies:
vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0
checksum: 10c0/67e7a31df0be1a6122d767b31f13164790ba884730bebeb5a07537f318f6d223e14a54e8f3d7780dcd0ccceeb350ae25540522e7f39ba7a644fc55a5fa7cad1e
languageName: node
linkType: hard

"vite-plugin-inspect@npm:^11.0.0":
version: 11.0.0
resolution: "vite-plugin-inspect@npm:11.0.0"
dependencies:
ansis: "npm:^3.16.0"
debug: "npm:^4.4.0"
error-stack-parser-es: "npm:^1.0.5"
ohash: "npm:^2.0.4"
open: "npm:^10.1.0"
perfect-debounce: "npm:^1.0.0"
sirv: "npm:^3.0.1"
unplugin-utils: "npm:^0.2.0"
vite-dev-rpc: "npm:^1.0.7"
peerDependencies:
vite: ^6.0.0
peerDependenciesMeta:
"@nuxt/kit":
optional: true
checksum: 10c0/808ef69ec2c3baec05f5024d634abb353b4916d1caaede5180560a9e74bafa4761ddde32f651a557ef080910a77d99ea42198081bb8fe1ea0a32891b7730fc8c
languageName: node
linkType: hard
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,15 @@ function getShallowestDependents(pkg: PackageNode) {
<div i-catppuccin-code-of-conduct icon-catppuccin ma />
</NuxtLink>
<button
v-if="backend?.functions.openInEditor"
v-if="backend?.functions.openInEditor && pkg.filepath"
title="Open Package Folder in Editor"
ml--1 w-8 h-8 rounded-full hover:bg-active flex
@click="backend.functions.openInEditor(pkg.filepath)"
>
<div i-catppuccin-folder-vscode hover:i-catppuccin-folder-vscode-open icon-catppuccin ma />
</button>
<button
v-if="backend?.functions.openInFinder"
v-if="backend?.functions.openInFinder && pkg.filepath"
title="Open Package Folder in Finder"
ml--1 w-8 h-8 rounded-full hover:bg-active flex
@click="backend.functions.openInFinder(pkg.filepath)"
Expand Down
5 changes: 5 additions & 0 deletions packages/node-modules-inspector/src/node/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export function createServerFunctions(options: CreateServerFunctionsOptions): Se
console.log('[Node Modules Inspector] No config found')
return result.config
})()

// Allow overriding CWD with env
if (process.env.NMI_CWD)
options.cwd = process.env.NMI_CWD

return _config
}

Expand Down
6 changes: 3 additions & 3 deletions packages/node-modules-tools/src/agent-entry/detect.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { AgentName } from 'package-manager-detector'
import type { Agent } from 'package-manager-detector'
import type { BaseOptions } from '../types'
import { detect } from 'package-manager-detector'

export async function getPackageManager(options: BaseOptions): Promise<AgentName> {
export async function getPackageManager(options: BaseOptions): Promise<Agent> {
const manager = await detect({
cwd: options.cwd,
})
if (!manager)
throw new Error('Cannot detect package manager in the current path')

return manager.name
return manager.agent
}
28 changes: 22 additions & 6 deletions packages/node-modules-tools/src/agent-entry/list.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AgentName } from 'package-manager-detector'
import type { Agent } from 'package-manager-detector'
import type { ListPackageDependenciesBaseResult, ListPackageDependenciesOptions, ListPackageDependenciesRawResult, PackageNodeBase } from '../types'

/**
Expand All @@ -7,14 +7,30 @@ import type { ListPackageDependenciesBaseResult, ListPackageDependenciesOptions,
* This function will automatically detect the package manager in the current project, and list the dependencies of the packages.
*/
export async function listPackageDependenciesRaw(
manager: AgentName,
manager: Agent,
options: ListPackageDependenciesOptions,
): Promise<ListPackageDependenciesRawResult> {
let result: ListPackageDependenciesRawResult
if (manager === 'pnpm')
result = await import('../agents/pnpm').then(r => r.listPackageDependencies(options))
else
throw new Error(`Package manager ${manager} is not yet supported`)

switch (manager) {
case 'pnpm':
case 'pnpm@6': {
result = await import('../agents/pnpm').then(r => r.listPackageDependencies(options))
break
}
case 'yarn@berry': {
console.warn('Yarn Berry support is experimental, if you encounter any issues, please open an issue with a reproduction')

@reteps reteps Mar 18, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need additional handrails to ensure

yarn config get nodeLinker is node-modules? Then the strategy outlined by @antfu would be guaranteed to work.

result = await import('../agents/berry').then(r => r.listPackageDependencies(options))
break
}
case 'npm':
case 'bun':
case 'deno':
case 'yarn':
throw new Error(`Package manager ${manager} is not yet supported`)
default:
throw new Error(`Unknown package manager: ${manager satisfies never}`)
}

return populateRawResult(result)
}
Expand Down
1 change: 1 addition & 0 deletions packages/node-modules-tools/src/agents/berry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { listPackageDependencies } from './list'
Loading