From 2f4d7178219523470d6b8330d8547d68e6c88a01 Mon Sep 17 00:00:00 2001 From: Wojciech Maj Date: Thu, 5 Feb 2026 23:12:54 +0100 Subject: [PATCH 1/5] feat: suggest installing dependency as devDependency when appropriate Closes #530 --- app/components/Terminal/Install.vue | 64 ++++++++++- app/pages/package/[[org]]/[name].vue | 1 + app/utils/install-command.ts | 114 +++++++++++++++++++- i18n/locales/en.json | 2 + i18n/locales/pl-PL.json | 2 + lunaria/files/en-GB.json | 2 + lunaria/files/en-US.json | 2 + lunaria/files/pl-PL.json | 2 + test/unit/app/utils/install-command.spec.ts | 90 ++++++++++++++++ 9 files changed, 277 insertions(+), 2 deletions(-) diff --git a/app/components/Terminal/Install.vue b/app/components/Terminal/Install.vue index 908cc2e8d..2a30f03e9 100644 --- a/app/components/Terminal/Install.vue +++ b/app/components/Terminal/Install.vue @@ -7,6 +7,7 @@ const props = defineProps<{ requestedVersion?: string | null installVersionOverride?: string | null jsrInfo?: JsrPackageInfo | null + readmeHtml?: string | null typesPackageName?: string | null executableInfo?: { hasExecutable: boolean; primaryCommand?: string } | null createPackageInfo?: { packageName: string } | null @@ -30,6 +31,20 @@ function getInstallPartsForPM(pmId: PackageManagerId) { }) } +const devDependencySuggestion = computed(() => + getDevDependencySuggestion(props.packageName, props.readmeHtml), +) + +function getDevInstallPartsForPM(pmId: PackageManagerId) { + return getInstallCommandParts({ + packageName: props.packageName, + packageManager: pmId, + version: props.requestedVersion, + jsrInfo: props.jsrInfo, + dev: true, + }) +} + // Generate run command parts for a specific package manager function getRunPartsForPM(pmId: PackageManagerId, command?: string) { return getRunCommandParts({ @@ -68,7 +83,7 @@ function getTypesInstallPartsForPM(pmId: PackageManagerId) { const pm = packageManagers.find(p => p.id === pmId) if (!pm) return [] - const devFlag = pmId === 'bun' ? '-d' : '-D' + const devFlag = getDevDependencyFlag(pmId) const pkgSpec = pmId === 'deno' ? `npm:${props.typesPackageName}` : props.typesPackageName return [pm.label, pm.action, devFlag, pkgSpec] @@ -95,6 +110,18 @@ const copyRunCommand = (command?: string) => copyRun(getFullRunCommand(command)) const { copied: createCopied, copy: copyCreate } = useClipboard({ copiedDuring: 2000 }) const copyCreateCommand = () => copyCreate(getFullCreateCommand()) + +const { copied: devInstallCopied, copy: copyDevInstall } = useClipboard({ copiedDuring: 2000 }) +const copyDevInstallCommand = () => + copyDevInstall( + getInstallCommand({ + packageName: props.packageName, + packageManager: selectedPM.value, + version: props.requestedVersion, + jsrInfo: props.jsrInfo, + dev: true, + }), + )