From 686c31f1c48cb7bd240fb5e8cdb58bf80e8b737a Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 28 Jun 2024 09:46:35 +0200 Subject: [PATCH] feat: allow installing peerDeps when using `addDependency` (#135) --- package.json | 1 + pnpm-lock.yaml | 43 ++++++++++++++++---------- src/api.ts | 35 +++++++++++++++++++++ src/types.ts | 1 + test/fixtures/bun-workspace/bun.lockb | Bin 1552 -> 1872 bytes 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index bb06ef7..b09fe92 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "consola": "^3.2.3", "execa": "^8.0.1", "pathe": "^1.1.2", + "pkg-types": "^1.1.1", "ufo": "^1.4.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0fcb963..aa744c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ dependencies: pathe: specifier: ^1.1.2 version: 1.1.2 + pkg-types: + specifier: ^1.1.1 + version: 1.1.1 ufo: specifier: ^1.4.0 version: 1.4.0 @@ -1196,7 +1199,6 @@ packages: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1346,7 +1348,7 @@ packages: ofetch: 1.3.3 pathe: 1.1.2 perfect-debounce: 1.0.0 - pkg-types: 1.0.3 + pkg-types: 1.1.1 scule: 1.3.0 untyped: 1.4.2 transitivePeerDependencies: @@ -1463,7 +1465,7 @@ packages: ohash: 1.1.3 pathe: 1.1.2 perfect-debounce: 1.0.0 - pkg-types: 1.0.3 + pkg-types: 1.1.1 rc9: 2.1.1 dev: true @@ -1551,7 +1553,7 @@ packages: ofetch: 1.3.3 open: 9.1.0 pathe: 1.1.2 - pkg-types: 1.0.3 + pkg-types: 1.1.1 scule: 1.3.0 semver: 7.6.0 std-env: 3.7.0 @@ -1649,6 +1651,9 @@ packages: resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==} dev: true + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + /consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -3217,10 +3222,6 @@ packages: hasBin: true dev: true - /jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - dev: true - /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: @@ -3257,7 +3258,7 @@ packages: engines: {node: '>=14'} dependencies: mlly: 1.6.1 - pkg-types: 1.0.3 + pkg-types: 1.1.1 dev: true /locate-path@5.0.0: @@ -3459,10 +3460,18 @@ packages: dependencies: acorn: 8.11.3 pathe: 1.1.2 - pkg-types: 1.0.3 + pkg-types: 1.1.1 ufo: 1.4.0 dev: true + /mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -3761,13 +3770,12 @@ packages: engines: {node: '>=8.6'} dev: true - /pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + /pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} dependencies: - jsonc-parser: 3.2.1 - mlly: 1.6.1 + confbox: 0.1.7 + mlly: 1.7.1 pathe: 1.1.2 - dev: true /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} @@ -4712,6 +4720,9 @@ packages: /ufo@1.4.0: resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -4748,7 +4759,7 @@ packages: mkdist: 1.4.0(typescript@5.4.2) mlly: 1.6.1 pathe: 1.1.2 - pkg-types: 1.0.3 + pkg-types: 1.1.1 pretty-bytes: 6.1.1 rollup: 3.29.4 rollup-plugin-dts: 6.1.0(rollup@3.29.4)(typescript@5.4.2) diff --git a/src/api.ts b/src/api.ts index 7cc8b5b..c4ad05a 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,3 +1,4 @@ +import { readPackageJSON } from "pkg-types"; import { executeCommand, resolveOperationOptions, @@ -71,6 +72,40 @@ export async function addDependency( cwd: resolvedOptions.cwd, silent: resolvedOptions.silent, }); + + if (options.installPeerDependencies) { + const existingPkg = await readPackageJSON(resolvedOptions.cwd); + const peerDeps: string[] = []; + const peerDevDeps: string[] = []; + for (const _name of names) { + const pkgName = _name.match(/^(.[^@]+)/)?.[0]; + const pkg = await readPackageJSON(pkgName, { + url: resolvedOptions.cwd, + }).catch(() => ({}) as Record); + if (!pkg.peerDependencies || name !== pkgName) { + continue; + } + for (const [peerDependency, version] of Object.entries( + pkg.peerDependencies, + )) { + if (pkg.peerDependenciesMeta?.[peerDependency]?.optional) { + continue; + } + // TODO: refactor to getSpecifiedPackageInfo later on + if ( + existingPkg.dependencies?.[peerDependency] || + existingPkg.devDependencies?.[peerDependency] + ) { + continue; + } + // TODO: Make sure peerDependency is not already installed in user project + const isDev = pkg.peerDependenciesMeta?.[peerDependency]?.dev; + (isDev ? peerDevDeps : peerDeps).push(`${peerDependency}@${version}`); + } + } + await addDependency(peerDeps, { ...resolvedOptions }); + await addDevDependency(peerDevDeps, { ...resolvedOptions }); + } } /** diff --git a/src/types.ts b/src/types.ts index 975c32e..f70b8d5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,6 +13,7 @@ export type OperationOptions = { cwd?: string; silent?: boolean; packageManager?: PackageManager | PackageManagerName; + installPeerDependencies?: boolean; dev?: boolean; workspace?: boolean | string; global?: boolean; diff --git a/test/fixtures/bun-workspace/bun.lockb b/test/fixtures/bun-workspace/bun.lockb index d9dd80dfe5d223730005b4cdce898b0bd9c40c2a..d8c703aa3933c51805153d1e01534a9e73cdebde 100755 GIT binary patch delta 267 zcmbQhbAfMyAJYN0jR8v;85t*kV+;q9eoWz$MVON&9^l<9!kok8RqkKpT^x|;yn~ei z3=TkPE}K#_6FUV9h2qSr)ciCZAS*E^Gd(XqjSH+UxmR+_X6s8EIoKfjEZ8PDGK=u1GC7)Jz7o~P%Q;enpmrLK-C`rTcr%OD!8O5GcO(4 RrG{{qPBvt8o?O5b0|1FfNcsQ( delta 45 zcmcb>H-Tq@A5#PC#(<@aj0}^%F@^(4Kc?`>7ufPAFJ(&FT*l1BH2EZ3`@{pB09*|Z AlK=n!