From 56a9fb897e2ddc19fed1d26e8d5fd2bfd553b537 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 18 Nov 2018 17:59:43 +0200 Subject: [PATCH] fix: external links shouldn't be added to shrinkwrap.yaml Links of packages that are not in package.json are not added to shrinkwrap.yaml. PR #1495 --- packages/headless/src/index.ts | 2 + packages/modules-cleaner/package.json | 1 + packages/modules-cleaner/src/index.ts | 2 - packages/modules-cleaner/src/prune.ts | 53 ++++++++++++++----- .../src/removeDirectDependency.ts | 9 ++-- packages/pnpm/src/cmd/prune.ts | 8 +-- packages/pnpm/test/index.ts | 1 + packages/pnpm/test/prune.ts | 20 +++++++ packages/supi/package.json | 1 + packages/supi/src/install/index.ts | 5 ++ packages/supi/src/install/link.ts | 2 + packages/supi/src/link/index.ts | 5 -- packages/supi/src/uninstall/index.ts | 39 +------------- packages/supi/src/unlink/index.ts | 33 +++--------- packages/supi/test/link.ts | 10 +--- packages/supi/test/prune.ts | 39 +++++++++++--- shrinkwrap.yaml | 7 ++- 17 files changed, 131 insertions(+), 106 deletions(-) create mode 100644 packages/pnpm/test/prune.ts diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index 961205d0a2..630f47d743 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -83,6 +83,7 @@ export interface HeadlessOptions { version: string, }, pruneStore: boolean, + pruneDirectDependencies?: boolean, wantedShrinkwrap?: Shrinkwrap, ownLifecycleHooksStdio?: 'inherit' | 'pipe', pendingBuilds: string[], @@ -143,6 +144,7 @@ export default async (opts: HeadlessOptions) => { importers: opts.importers, newShrinkwrap: filterShrinkwrap(wantedShrinkwrap, filterOpts), oldShrinkwrap: currentShrinkwrap, + pruneDirectDependencies: opts.pruneDirectDependencies, pruneStore: opts.pruneStore, registries: opts.registries, shrinkwrapDirectory, diff --git a/packages/modules-cleaner/package.json b/packages/modules-cleaner/package.json index 9d7c46c45d..c9e836609d 100644 --- a/packages/modules-cleaner/package.json +++ b/packages/modules-cleaner/package.json @@ -32,6 +32,7 @@ "dependencies": { "@pnpm/core-loggers": "1.0.0", "@pnpm/package-bins": "2.0.0", + "@pnpm/read-modules-dir": "0.0.0", "@pnpm/store-controller-types": "1.1.0", "@pnpm/types": "2.0.0", "@pnpm/utils": "0.9.0", diff --git a/packages/modules-cleaner/src/index.ts b/packages/modules-cleaner/src/index.ts index 61f1fd9026..0855a39580 100644 --- a/packages/modules-cleaner/src/index.ts +++ b/packages/modules-cleaner/src/index.ts @@ -1,7 +1,5 @@ import prune from './prune' -import removeDirectDependency from './removeDirectDependency' export { prune, - removeDirectDependency, } diff --git a/packages/modules-cleaner/src/prune.ts b/packages/modules-cleaner/src/prune.ts index b9c87371a4..e118d60511 100644 --- a/packages/modules-cleaner/src/prune.ts +++ b/packages/modules-cleaner/src/prune.ts @@ -3,19 +3,24 @@ import { statsLogger, } from '@pnpm/core-loggers' import logger from '@pnpm/logger' +import readModulesDir from '@pnpm/read-modules-dir' import { StoreController } from '@pnpm/store-controller-types' import { DEPENDENCIES_FIELDS, Registries } from '@pnpm/types' import * as dp from 'dependency-path' import vacuumCB = require('fs-vacuum') import path = require('path') -import { ResolvedPackages, Shrinkwrap } from 'pnpm-shrinkwrap' +import { + ResolvedPackages, + Shrinkwrap, + ShrinkwrapImporter, +} from 'pnpm-shrinkwrap' import R = require('ramda') import promisify = require('util.promisify') import removeDirectDependency from './removeDirectDependency' const vacuum = promisify(vacuumCB) -export default async function removeOrphanPkgs ( +export default async function prune ( opts: { dryRun?: boolean, importers: Array<{ @@ -28,27 +33,45 @@ export default async function removeOrphanPkgs ( }>, newShrinkwrap: Shrinkwrap, oldShrinkwrap: Shrinkwrap, + pruneDirectDependencies?: boolean, pruneStore?: boolean, registries: Registries, + removePackages?: string[], virtualStoreDir: string, shrinkwrapDirectory: string, storeController: StoreController, }, ): Promise> { - await Promise.all(opts.importers.map((importer) => { - const oldImporterShr = opts.oldShrinkwrap.importers[importer.id] || {} - const oldPkgs = R.toPairs(R.mergeAll(R.map((depType) => oldImporterShr[depType], DEPENDENCIES_FIELDS))) - const newPkgs = R.toPairs(R.mergeAll(R.map((depType) => opts.newShrinkwrap.importers[importer.id][depType], DEPENDENCIES_FIELDS))) + await Promise.all(opts.importers.map(async (importer) => { + const oldImporterShr = opts.oldShrinkwrap.importers[importer.id] || {} as ShrinkwrapImporter + const oldPkgs = R.toPairs(mergeDependencies(oldImporterShr)) + const newPkgs = R.toPairs(mergeDependencies(opts.newShrinkwrap.importers[importer.id])) - const removedTopDeps: Array<[string, string]> = R.difference(oldPkgs, newPkgs) as Array<[string, string]> + const depsToRemove = new Set([ + ...opts.removePackages || [], + ...R.difference(oldPkgs, newPkgs).map(([depName]) => depName), + ]) + if (opts.pruneDirectDependencies) { + const allCurrentPackages = await readModulesDir(importer.modulesDir) || [] + if (allCurrentPackages.length > 0) { + const newPkgsSet = new Set(newPkgs.map(([depName]) => depName)) + for (const currentPackage of allCurrentPackages) { + if (!newPkgsSet.has(currentPackage)) { + depsToRemove.add(currentPackage) + } + } + } + } const { bin, modulesDir, prefix } = importer - return Promise.all(removedTopDeps.map((depName) => { + return Promise.all(Array.from(depsToRemove).map((depName) => { return removeDirectDependency({ - dev: Boolean(oldImporterShr.devDependencies && oldImporterShr.devDependencies[depName[0]]), - name: depName[0], - optional: Boolean(oldImporterShr.optionalDependencies && oldImporterShr.optionalDependencies[depName[0]]), + dependenciesField: oldImporterShr.devDependencies && oldImporterShr.devDependencies[depName] && 'devDependencies' || + oldImporterShr.optionalDependencies && oldImporterShr.optionalDependencies[depName] && 'optionalDependencies' || + oldImporterShr.dependencies && oldImporterShr.dependencies[depName] && 'dependencies' || + undefined, + name: depName, }, { bin, dryRun: opts.dryRun, @@ -81,9 +104,7 @@ export default async function removeOrphanPkgs ( if (hoistedAliases[orphanDepPath]) { await Promise.all(hoistedAliases[orphanDepPath].map((alias) => { return removeDirectDependency({ - dev: false, name: alias, - optional: false, }, { bin, modulesDir, @@ -130,6 +151,12 @@ export default async function removeOrphanPkgs ( return new Set(orphanDepPaths) } +function mergeDependencies (shrImporter: ShrinkwrapImporter): { [depName: string]: string } { + return R.mergeAll( + DEPENDENCIES_FIELDS.map((depType) => shrImporter[depType]), + ) +} + function getPkgsDepPaths ( registry: string, packages: ResolvedPackages, diff --git a/packages/modules-cleaner/src/removeDirectDependency.ts b/packages/modules-cleaner/src/removeDirectDependency.ts index 68ccea353c..dfab4e7c63 100644 --- a/packages/modules-cleaner/src/removeDirectDependency.ts +++ b/packages/modules-cleaner/src/removeDirectDependency.ts @@ -3,15 +3,15 @@ import { rootLogger, } from '@pnpm/core-loggers' import binify from '@pnpm/package-bins' +import { DependenciesField } from '@pnpm/types' import { safeReadPackageFromDir } from '@pnpm/utils' import path = require('path') import rimraf = require('rimraf-then') export default async function removeDirectDependency ( dependency: { - dev: boolean, + dependenciesField?: DependenciesField | undefined, name: string, - optional: boolean, }, opts: { bin: string, @@ -31,7 +31,10 @@ export default async function removeDirectDependency ( rootLogger.debug({ prefix: opts.prefix, removed: { - dependencyType: dependency.dev && 'dev' || dependency.optional && 'optional' || 'prod', + dependencyType: dependency.dependenciesField === 'devDependencies' && 'dev' || + dependency.dependenciesField === 'optionalDependencies' && 'optional' || + dependency.dependenciesField === 'dependencies' && 'prod' || + undefined, name: dependency.name, version: uninstalledPkg && uninstalledPkg.version, }, diff --git a/packages/pnpm/src/cmd/prune.ts b/packages/pnpm/src/cmd/prune.ts index 80ddec024d..f64a52ad35 100644 --- a/packages/pnpm/src/cmd/prune.ts +++ b/packages/pnpm/src/cmd/prune.ts @@ -4,9 +4,11 @@ import { PnpmOptions } from '../types' export default async (input: string[], opts: PnpmOptions) => { const store = await createStoreController(opts) - const pruneOpts = Object.assign(opts, { + return install({ + ...opts, + pruneDirectDependencies: true, + pruneStore: true, store: store.path, storeController: store.ctrl, - }) - return install({ ...pruneOpts, pruneStore: true } as InstallOptions) + } as InstallOptions) } diff --git a/packages/pnpm/test/index.ts b/packages/pnpm/test/index.ts index 6481423e31..eb4c6c284b 100644 --- a/packages/pnpm/test/index.ts +++ b/packages/pnpm/test/index.ts @@ -6,6 +6,7 @@ import './link' import './list' import './monorepo' import './outdated' +import './prune' import './rebuild' import './recursive' import './root' diff --git a/packages/pnpm/test/prune.ts b/packages/pnpm/test/prune.ts new file mode 100644 index 0000000000..ace3196229 --- /dev/null +++ b/packages/pnpm/test/prune.ts @@ -0,0 +1,20 @@ +import prepare from '@pnpm/prepare' +import path = require('path') +import tape = require('tape') +import promisifyTape from 'tape-promise' +import { execPnpm, pathToLocalPkg } from './utils' + +const test = promisifyTape(tape) +const testOnly = promisifyTape(tape.only) + +test('prune removes external link that is not in package.json', async function (t: tape.Test) { + const project = prepare(t) + + await execPnpm('link', path.relative(process.cwd(), pathToLocalPkg('local-pkg'))) + + await project.has('local-pkg') + + await execPnpm('prune') + + await project.hasNot('local-pkg') +}) diff --git a/packages/supi/package.json b/packages/supi/package.json index c47bd9dd1e..4feb636903 100644 --- a/packages/supi/package.json +++ b/packages/supi/package.json @@ -30,6 +30,7 @@ "@pnpm/package-requester": "4.1.10", "@pnpm/pkgid-to-filename": "2.0.0", "@pnpm/read-manifests": "1.0.0-1", + "@pnpm/read-modules-dir": "0.0.0", "@pnpm/read-package-json": "1.0.1", "@pnpm/resolve-dependencies": "1.0.8", "@pnpm/resolver-base": "2.0.0", diff --git a/packages/supi/src/install/index.ts b/packages/supi/src/install/index.ts index 51233dda89..8ee3bd07c3 100644 --- a/packages/supi/src/install/index.ts +++ b/packages/supi/src/install/index.ts @@ -74,6 +74,7 @@ export async function install (maybeOpts: InstallOptions & { type: 'version' | 'range' | 'tag', }, }, + pruneDirectDependencies?: boolean, }) { const reporter = maybeOpts && maybeOpts.reporter if (reporter) { @@ -221,6 +222,7 @@ export async function install (maybeOpts: InstallOptions & { }) } await installInContext(importersToInstall, ctx, { + pruneDirectDependencies: false, ...opts, makePartialCurrentShrinkwrap: false, updatePackageJson: false, @@ -446,6 +448,7 @@ export async function installPkgs ( { ...opts, makePartialCurrentShrinkwrap, + pruneDirectDependencies: false, updatePackageJson: true, updateShrinkwrapMinorVersion: R.isEmpty(ctx.currentShrinkwrap.packages), }, @@ -481,6 +484,7 @@ async function installInContext ( type: 'version' | 'range' | 'tag', }, }, + pruneDirectDependencies: boolean, }, ) { if (opts.shrinkwrapOnly && ctx.existsCurrentShrinkwrap) { @@ -648,6 +652,7 @@ async function installInContext ( independentLeaves: opts.independentLeaves, makePartialCurrentShrinkwrap: opts.makePartialCurrentShrinkwrap, outdatedDependencies, + pruneDirectDependencies: opts.pruneDirectDependencies, pruneStore: opts.pruneStore, registries: ctx.registries, shrinkwrapDirectory: opts.shrinkwrapDirectory, diff --git a/packages/supi/src/install/link.ts b/packages/supi/src/install/link.ts index 93c1e4c72f..3003c0500c 100644 --- a/packages/supi/src/install/link.ts +++ b/packages/supi/src/install/link.ts @@ -59,6 +59,7 @@ export default async function linkPackages ( wantedShrinkwrap: Shrinkwrap, currentShrinkwrap: Shrinkwrap, makePartialCurrentShrinkwrap: boolean, + pruneDirectDependencies: boolean, pruneStore: boolean, registries: Registries, shrinkwrapDirectory: string, @@ -142,6 +143,7 @@ export default async function linkPackages ( importers, newShrinkwrap: filterShrinkwrap(newShrinkwrap, filterOpts), oldShrinkwrap: opts.currentShrinkwrap, + pruneDirectDependencies: opts.pruneDirectDependencies, pruneStore: opts.pruneStore, registries: opts.registries, shrinkwrapDirectory: opts.shrinkwrapDirectory, diff --git a/packages/supi/src/link/index.ts b/packages/supi/src/link/index.ts index 084a21aadf..4b5c50f275 100644 --- a/packages/supi/src/link/index.ts +++ b/packages/supi/src/link/index.ts @@ -174,11 +174,6 @@ function addLinkToShrinkwrap ( } } - if (!addedTo) { - shrImporter.dependencies = shrImporter.dependencies || {} - shrImporter.dependencies[opts.linkedPkgName] = id - } - // package.json might not be available when linking to global if (!opts.pkg) return diff --git a/packages/supi/src/uninstall/index.ts b/packages/supi/src/uninstall/index.ts index 1994355e0b..0ec4519755 100644 --- a/packages/supi/src/uninstall/index.ts +++ b/packages/supi/src/uninstall/index.ts @@ -1,6 +1,6 @@ import { summaryLogger } from '@pnpm/core-loggers' import logger, { streamParser } from '@pnpm/logger' -import { prune, removeDirectDependency } from '@pnpm/modules-cleaner' +import { prune } from '@pnpm/modules-cleaner' import { write as writeModulesYaml } from '@pnpm/modules-yaml' import { shamefullyFlattenByShrinkwrap } from '@pnpm/shamefully-flatten' import { getSaveType } from '@pnpm/utils' @@ -14,7 +14,6 @@ import { import { LAYOUT_VERSION } from '../constants' import { getContextForSingleImporter, PnpmSingleContext } from '../getContext' import lock from '../lock' -import safeIsInnerLink from '../safeIsInnerLink' import shrinkwrapsEqual from '../shrinkwrapsEqual' import extendOptions, { StrictUninstallOptions, @@ -87,6 +86,7 @@ export async function uninstallInContext ( newShrinkwrap: newShr, oldShrinkwrap: ctx.currentShrinkwrap, registries: ctx.registries, + removePackages: pkgsToUninstall, shrinkwrapDirectory: opts.shrinkwrapDirectory, storeController: opts.storeController, virtualStoreDir: ctx.virtualStoreDir, @@ -102,11 +102,6 @@ export async function uninstallInContext ( } else { await saveCurrentShrinkwrapOnly(ctx.shrinkwrapDirectory, currentShrinkwrap, shrinkwrapOpts) } - await removeOuterLinks(pkgsToUninstall, ctx.modulesDir, { - bin: opts.bin, - prefix: opts.prefix, - storePath: ctx.storePath, - }) if (opts.shamefullyFlatten) { ctx.hoistedAliases = await shamefullyFlattenByShrinkwrap(currentShrinkwrap, ctx.importerId, { @@ -137,33 +132,3 @@ export async function uninstallInContext ( summaryLogger.debug({ prefix: opts.prefix }) } - -async function removeOuterLinks ( - pkgsToUninstall: string[], - modulesDir: string, - opts: { - bin: string, - storePath: string, - prefix: string, - }, -) { - const safeIsInnerLinkOpts = { - hideAlienModules: true, - prefix: opts.prefix, - storePath: opts.storePath, - } - // These packages are not in package.json, they were just linked in not installed - for (const pkgToUninstall of pkgsToUninstall) { - if (await safeIsInnerLink(modulesDir, pkgToUninstall, safeIsInnerLinkOpts) !== true) { - await removeDirectDependency({ - dev: false, - name: pkgToUninstall, - optional: false, - }, { - bin: opts.bin, - modulesDir, - prefix: opts.prefix, - }) - } - } -} diff --git a/packages/supi/src/unlink/index.ts b/packages/supi/src/unlink/index.ts index 678caf48d9..78c006a8c9 100644 --- a/packages/supi/src/unlink/index.ts +++ b/packages/supi/src/unlink/index.ts @@ -1,9 +1,10 @@ import logger, { streamParser } from '@pnpm/logger' +import readModulesDirs from '@pnpm/read-modules-dir' import { fromDir as readPkgFromDir } from '@pnpm/read-package-json' import { getAllDependenciesFromPackage } from '@pnpm/utils' import isInnerLink = require('is-inner-link') import isSubdir = require('is-subdir') -import fs = require('mz/fs') +import pFilter = require('p-filter') import path = require('path') import rimraf = require('rimraf-then') import getContext from '../getContext' @@ -80,7 +81,11 @@ export async function unlink (maybeOpts: InstallOptions) { if (ctx.importers.length > 1) throw new Error('Unlink not implemented for multiple importers yet') const importer = ctx.importers[0] - const externalPackages = await getExternalPackages(importer.modulesDir, opts.store) + const packageDirs = await readModulesDirs(importer.modulesDir) + const externalPackages = await pFilter( + packageDirs, + (packageDir: string) => isExternalLink(opts.store, importer.modulesDir, packageDir), + ) await _unlinkPkgs(externalPackages, opts, ctx.importers) @@ -89,30 +94,6 @@ export async function unlink (maybeOpts: InstallOptions) { } } -async function getExternalPackages ( - modules: string, - store: string, - scope?: string, -): Promise { - let externalLinks: string[] = [] - const parentDir = scope ? path.join(modules, scope) : modules - for (const dir of await fs.readdir(parentDir)) { - if (dir[0] === '.') continue - - if (!scope && dir[0] === '@') { - externalLinks = externalLinks.concat(await getExternalPackages(modules, store, dir)) - continue - } - - const pkgName = scope ? `${scope}/${dir}` : dir - - if (await isExternalLink(store, modules, pkgName)) { - externalLinks.push(pkgName) - } - } - return externalLinks -} - async function isExternalLink (store: string, modules: string, pkgName: string) { const link = await isInnerLink(modules, pkgName) diff --git a/packages/supi/test/link.ts b/packages/supi/test/link.ts index 5d5a8486a0..6b149e732f 100644 --- a/packages/supi/test/link.ts +++ b/packages/supi/test/link.ts @@ -103,13 +103,7 @@ test('relative link is not rewritten by argumentless install', async (t: tape.Te await install(opts) - t.ok(project.requireModule('hello-world-js-bin/package.json').isLocal) - - const wantedShrinkwrap = await project.loadShrinkwrap() - t.equal(wantedShrinkwrap.dependencies['hello-world-js-bin'], 'link:../hello-world-js-bin', 'link still in wanted shrinkwrap') - - const currentShrinkwrap = await project.loadCurrentShrinkwrap() - t.equal(currentShrinkwrap.dependencies['hello-world-js-bin'], 'link:../hello-world-js-bin', 'link still in current shrinkwrap') + t.ok(project.requireModule('hello-world-js-bin/package.json').isLocal, 'link is not removed by installation') }) test('relative link is rewritten by named installation to regular dependency', async (t: tape.Test) => { @@ -250,7 +244,7 @@ test('relative link uses realpath when contained in a symlinked dir', async (t: } }) -test('relative link when an external shrinkwrap is used', async (t) => { +test['skip']('relative link when an external shrinkwrap is used', async (t: tape.Test) => { const projects = prepare(t, [ { name: 'project', diff --git a/packages/supi/test/prune.ts b/packages/supi/test/prune.ts index f61de6041a..0e88f29d63 100644 --- a/packages/supi/test/prune.ts +++ b/packages/supi/test/prune.ts @@ -1,10 +1,17 @@ import prepare from '@pnpm/prepare' +import path = require('path') import readPkg = require('read-pkg') -import { install, installPkgs } from 'supi' +import sinon = require('sinon') +import { + install, + installPkgs, + link, + RootLog, +} from 'supi' import tape = require('tape') import promisifyTape from 'tape-promise' import writePkg = require('write-pkg') -import { testDefaults } from './utils' +import { pathToLocalPkg, testDefaults } from './utils' const test = promisifyTape(tape) const testOnly = promisifyTape(tape.only) @@ -12,10 +19,14 @@ const testOnly = promisifyTape(tape.only) test('prune removes extraneous packages', async (t: tape.Test) => { const project = prepare(t) - await installPkgs(['is-negative@2.1.0'], await testDefaults({ save: true })) - await installPkgs(['applyq@0.2.1'], await testDefaults({ saveDev: true })) - await installPkgs(['fnumber@0.1.0'], await testDefaults({ saveOptional: true })) - await installPkgs(['is-positive@2.0.0', '@zkochan/logger@0.1.0'], await testDefaults()) + const opts = await testDefaults() + await installPkgs(['is-negative@2.1.0'], { ...opts, saveProd: true }) + await installPkgs(['applyq@0.2.1'], { ...opts, saveDev: true }) + await installPkgs(['fnumber@0.1.0'], { ...opts, saveOptional: true }) + await installPkgs(['is-positive@2.0.0', '@zkochan/logger@0.1.0'], opts) + await link([pathToLocalPkg('hello-world-js-bin')], path.resolve(process.cwd(), 'node_modules'), opts) + + await project.has('hello-world-js-bin') // external link added const pkg = await readPkg() @@ -24,7 +35,21 @@ test('prune removes extraneous packages', async (t: tape.Test) => { await writePkg(pkg) - await install(await testDefaults({ pruneStore: true })) + const reporter = sinon.spy() + + await install({ ...opts, pruneDirectDependencies: true, pruneStore: true, reporter }) + + t.ok(reporter.calledWithMatch({ + level: 'debug', + name: 'pnpm:root', + removed: { + dependencyType: undefined, + name: 'hello-world-js-bin', + version: '1.0.0', + }, + } as RootLog), 'removing link to external package') + + await project.hasNot('hello-world-js-bin') // external link pruned await project.storeHasNot('is-positive', '2.0.0') await project.hasNot('is-positive') diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 25bb1a575c..cec444c52d 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -465,6 +465,7 @@ importers: dependencies: '@pnpm/core-loggers': 'link:../core-loggers' '@pnpm/package-bins': 2.0.0 + '@pnpm/read-modules-dir': 'link:../read-modules-dir' '@pnpm/store-controller-types': 'link:../store-controller-types' '@pnpm/types': 'link:../types' '@pnpm/utils': 'link:../utils' @@ -488,6 +489,7 @@ importers: '@pnpm/logger': 2.1.0 '@pnpm/modules-cleaner': 'link:' '@pnpm/package-bins': 2.0.0 + '@pnpm/read-modules-dir': 0.0.0 '@pnpm/store-controller-types': 1.1.0 '@pnpm/tslint-config': 0.0.0 '@pnpm/types': 2.0.0 @@ -1238,6 +1240,7 @@ importers: '@pnpm/package-requester': 'link:../package-requester' '@pnpm/pkgid-to-filename': 2.0.0 '@pnpm/read-manifests': 'link:../read-manifests' + '@pnpm/read-modules-dir': 'link:../read-modules-dir' '@pnpm/read-package-json': 1.0.1 '@pnpm/resolve-dependencies': 'link:../resolve-dependencies' '@pnpm/resolver-base': 2.0.0 @@ -1348,6 +1351,7 @@ importers: '@pnpm/pkgid-to-filename': 2.0.0 '@pnpm/prepare': 0.0.0 '@pnpm/read-manifests': 1.0.0-1 + '@pnpm/read-modules-dir': 0.0.0 '@pnpm/read-package-json': 1.0.1 '@pnpm/resolve-dependencies': 1.0.8 '@pnpm/resolver-base': 2.0.0 @@ -2189,7 +2193,7 @@ packages: integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== /@types/mz/0.0.32: dependencies: - '@types/node': 10.12.5 + '@types/node': 10.12.9 resolution: integrity: sha512-cy3yebKhrHuOcrJGkfwNHhpTXQLgmXSv1BX+4p32j+VUQ6aP2eJ5cL7OvGcAQx75fCTFaAIIAKewvqL+iwSd4g== /@types/ncp/2.0.1: @@ -2211,7 +2215,6 @@ packages: resolution: integrity: sha512-+ZWB5Ec1iki99xQFzBlivlKxSZQ+fuUKBott8StBOnLN4dWbRHlgdg1XknpW6g0tweniN5DcOqA64CJyOUPSAw== /@types/node/10.12.9: - dev: false resolution: integrity: sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA== /@types/node/8.10.37: