From e379ec8a770b060081e501cec4d76d54aa7e4c4e Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sat, 19 Nov 2022 04:29:21 +0200 Subject: [PATCH] refactor: use more utils from ramda (#5656) --- packages/audit/package.json | 4 +- packages/audit/src/lockfileToAuditTree.ts | 9 +- packages/build-modules/src/buildSequence.ts | 2 +- packages/build-modules/src/index.ts | 11 +- packages/client/package.json | 6 +- packages/client/src/index.ts | 10 +- packages/core/package.json | 1 + packages/core/src/install/index.ts | 78 +++++------ packages/core/src/install/link.ts | 24 ++-- packages/dependencies-hierarchy/src/index.ts | 12 +- packages/dependency-path/src/index.ts | 2 +- packages/exportable-manifest/package.json | 1 + packages/exportable-manifest/src/index.ts | 19 ++- .../filter-lockfile/src/filterImporter.ts | 2 +- .../filter-lockfile/src/filterLockfile.ts | 14 +- .../src/filterLockfileByImportersAndEngine.ts | 22 +-- .../test/filterByImportersAndEngine.ts | 22 +-- packages/headless/src/index.ts | 35 ++--- packages/headless/src/lockfileToDepGraph.ts | 25 ++-- packages/hoist/src/index.ts | 10 +- packages/license-scanner/package.json | 3 +- .../src/lockfileToLicenseNodeTree.ts | 9 +- .../lockfile-file/src/sortLockfileKeys.ts | 8 +- packages/lockfile-file/src/write.ts | 15 +-- packages/lockfile-to-pnp/src/index.ts | 3 +- packages/lockfile-types/src/index.ts | 4 +- packages/make-dedicated-lockfile/src/index.ts | 7 +- packages/modules-cleaner/src/prune.ts | 18 +-- packages/modules-yaml/package.json | 2 + packages/modules-yaml/src/index.ts | 13 +- packages/normalize-registries/package.json | 6 +- packages/normalize-registries/src/index.ts | 10 +- packages/package-requester/package.json | 1 + .../package-requester/src/packageRequester.ts | 27 ++-- packages/parse-cli-args/src/index.ts | 4 +- packages/pkgs-graph/src/index.ts | 20 +-- .../src/import/index.ts | 31 ++--- .../src/updateWorkspaceDependencies.ts | 14 +- .../src/storeStatus/index.ts | 7 +- packages/prune-lockfile/src/index.ts | 12 +- .../src/getNonDevWantedDependencies.ts | 14 +- .../src/getWantedDependencies.ts | 10 +- packages/resolve-dependencies/src/index.ts | 4 +- .../src/resolveDependencies.ts | 25 ++-- .../src/resolveDependencyTree.ts | 4 +- .../resolve-dependencies/src/resolvePeers.ts | 21 +-- .../src/toResolveImporter.ts | 12 +- .../src/updateLockfile.ts | 12 +- packages/tarball-fetcher/package.json | 1 + .../src/gitHostedTarballFetcher.ts | 25 ++-- packages/types/src/package.ts | 4 +- pnpm-lock.yaml | 127 +++++++++++++++--- typings/local.d.ts | 5 + 53 files changed, 406 insertions(+), 381 deletions(-) diff --git a/packages/audit/package.json b/packages/audit/package.json index 3bf9f984a8..8be243f2b0 100644 --- a/packages/audit/package.json +++ b/packages/audit/package.json @@ -33,6 +33,7 @@ "@pnpm/audit": "workspace:*", "@pnpm/constants": "workspace:*", "@pnpm/lockfile-file": "workspace:*", + "@types/ramda": "0.28.15", "nock": "13.2.9" }, "dependencies": { @@ -42,7 +43,8 @@ "@pnpm/lockfile-types": "workspace:*", "@pnpm/lockfile-utils": "workspace:*", "@pnpm/lockfile-walker": "workspace:*", - "@pnpm/types": "workspace:*" + "@pnpm/types": "workspace:*", + "ramda": "npm:@pnpm/ramda@0.28.1" }, "funding": "https://opencollective.com/pnpm", "exports": { diff --git a/packages/audit/src/lockfileToAuditTree.ts b/packages/audit/src/lockfileToAuditTree.ts index 21d68b4494..cc00720010 100644 --- a/packages/audit/src/lockfileToAuditTree.ts +++ b/packages/audit/src/lockfileToAuditTree.ts @@ -2,6 +2,7 @@ import { Lockfile } from '@pnpm/lockfile-types' import { nameVerFromPkgSnapshot } from '@pnpm/lockfile-utils' import { lockfileWalkerGroupImporterSteps, LockfileWalkerStep } from '@pnpm/lockfile-walker' import { DependenciesField } from '@pnpm/types' +import mapValues from 'ramda/src/map' export interface AuditNode { version?: string @@ -71,10 +72,6 @@ function lockfileToAuditNode (step: LockfileWalkerStep) { return dependencies } -function toRequires (auditNodesByDepName: Record) { - const requires = {} - for (const subdepName of Object.keys(auditNodesByDepName)) { - requires[subdepName] = auditNodesByDepName[subdepName].version - } - return requires +function toRequires (auditNodesByDepName: Record): Record { + return mapValues((auditNode) => auditNode.version!, auditNodesByDepName) } diff --git a/packages/build-modules/src/buildSequence.ts b/packages/build-modules/src/buildSequence.ts index 42d5f37b97..f386e0e04f 100644 --- a/packages/build-modules/src/buildSequence.ts +++ b/packages/build-modules/src/buildSequence.ts @@ -3,7 +3,7 @@ import { PackageManifest, PatchFile } from '@pnpm/types' import filter from 'ramda/src/filter' export interface DependenciesGraphNode { - children: { [alias: string]: string } + children: Record depPath: string dir: string fetchingBundledManifest?: () => Promise diff --git a/packages/build-modules/src/index.ts b/packages/build-modules/src/index.ts index 00dd6dab47..82a8d35add 100644 --- a/packages/build-modules/src/index.ts +++ b/packages/build-modules/src/index.ts @@ -9,6 +9,7 @@ import { readPackageJsonFromDir, safeReadPackageJsonFromDir } from '@pnpm/read-p import { StoreController } from '@pnpm/store-controller-types' import { DependencyManifest } from '@pnpm/types' import { applyPatch } from 'patch-package/dist/applyPatches' +import pickBy from 'ramda/src/pickBy' import runGroups from 'run-groups' import { buildSequence, DependenciesGraph, DependenciesGraphNode } from './buildSequence' @@ -174,15 +175,9 @@ export async function linkBinsOfDependencies ( warn: (message: string) => void } ) { - const childrenToLink = opts.optional + const childrenToLink: Record = opts.optional ? depNode.children - : Object.keys(depNode.children) - .reduce((nonOptionalChildren, childAlias) => { - if (!depNode.optionalDependencies.has(childAlias)) { - nonOptionalChildren[childAlias] = depNode.children[childAlias] - } - return nonOptionalChildren - }, {}) + : pickBy((child, childAlias) => !depNode.optionalDependencies.has(childAlias), depNode.children) const binPath = path.join(depNode.dir, 'node_modules/.bin') diff --git a/packages/client/package.json b/packages/client/package.json index 04db27089a..a160256fe8 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -38,11 +38,13 @@ "@pnpm/git-fetcher": "workspace:*", "@pnpm/network.auth-header": "workspace:*", "@pnpm/resolver-base": "workspace:*", - "@pnpm/tarball-fetcher": "workspace:*" + "@pnpm/tarball-fetcher": "workspace:*", + "ramda": "npm:@pnpm/ramda@0.28.1" }, "devDependencies": { "@pnpm/client": "workspace:*", - "@pnpm/fetcher-base": "workspace:*" + "@pnpm/fetcher-base": "workspace:*", + "@types/ramda": "0.28.15" }, "funding": "https://opencollective.com/pnpm", "exports": { diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 1d258ef0a0..ee5d3fe1a2 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -10,6 +10,7 @@ import { createDirectoryFetcher } from '@pnpm/directory-fetcher' import { createGitFetcher } from '@pnpm/git-fetcher' import { createTarballFetcher, TarballFetchers } from '@pnpm/tarball-fetcher' import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header' +import mapValues from 'ramda/src/map' export { ResolveFunction } @@ -61,11 +62,10 @@ function createFetchers ( ...createDirectoryFetcher({ resolveSymlinks: opts.resolveSymlinksInInjectedDirs }), } - const overwrites = Object.entries(customFetchers ?? {}) - .reduce((acc, [fetcherName, factory]) => { - acc[fetcherName] = factory({ defaultFetchers }) - return acc - }, {}) + const overwrites = mapValues( + (factory: any) => factory({ defaultFetchers }), // eslint-disable-line @typescript-eslint/no-explicit-any + customFetchers ?? {} as any // eslint-disable-line @typescript-eslint/no-explicit-any + ) return { ...defaultFetchers, diff --git a/packages/core/package.json b/packages/core/package.json index 083e31b30d..3f7cda38db 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -60,6 +60,7 @@ "p-every": "^2.0.0", "p-filter": "^2.1.0", "p-limit": "^3.1.0", + "p-map-values": "^1.0.0", "path-exists": "^4.0.0", "ramda": "npm:@pnpm/ramda@0.28.1", "run-groups": "^3.0.1", diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index 4d817b055e..fb162eb1bd 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -60,10 +60,13 @@ import rimraf from '@zkochan/rimraf' import isInnerLink from 'is-inner-link' import pFilter from 'p-filter' import pLimit from 'p-limit' +import pMapValues from 'p-map-values' import flatten from 'ramda/src/flatten' import fromPairs from 'ramda/src/fromPairs' +import mapValues from 'ramda/src/map' import equals from 'ramda/src/equals' import isEmpty from 'ramda/src/isEmpty' +import pickBy from 'ramda/src/pickBy' import pipeWith from 'ramda/src/pipeWith' import props from 'ramda/src/props' import unnest from 'ramda/src/unnest' @@ -271,10 +274,10 @@ export async function mutateModules ( ? ctx.wantedLockfile.patchedDependencies : (opts.patchedDependencies ? await calcPatchHashes(opts.patchedDependencies, opts.lockfileDir) : {}) const patchedDependenciesWithResolvedPath = patchedDependencies - ? fromPairs(Object.entries(patchedDependencies).map(([key, patchFile]) => [key, { + ? mapValues((patchFile) => ({ hash: patchFile.hash, path: path.join(opts.lockfileDir, patchFile.path), - }])) + }), patchedDependencies) : undefined let needsFullResolution = !maybeOpts.ignorePackageManifest && lockfileIsUpToDate(ctx.wantedLockfile, { @@ -561,18 +564,13 @@ export async function mutateModules ( } async function calcPatchHashes (patches: Record, lockfileDir: string) { - return fromPairs(await Promise.all( - Object.entries(patches).map(async ([key, patchFileRelativePath]) => { - const patchFilePath = path.join(lockfileDir, patchFileRelativePath) - return [ - key, - { - hash: await createBase32HashFromFile(patchFilePath), - path: patchFileRelativePath, - }, - ] - }) - )) + return pMapValues(async (patchFileRelativePath) => { + const patchFilePath = path.join(lockfileDir, patchFileRelativePath) + return { + hash: await createBase32HashFromFile(patchFilePath), + path: patchFileRelativePath, + } + }, patches) } function lockfileIsUpToDate ( @@ -782,16 +780,13 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => { (ctx.wantedLockfile.packages != null) && !isEmpty(ctx.wantedLockfile.packages) ) { - ctx.wantedLockfile.packages = Object.entries(ctx.wantedLockfile.packages).reduce((pre, [depPath, snapshot]) => ({ - ...pre, - [depPath]: { - // These fields are needed to avoid losing information of the locked dependencies if these fields are not broken - // If these fields are broken, they will also be regenerated - dependencies: snapshot.dependencies, - optionalDependencies: snapshot.optionalDependencies, - resolution: snapshot.resolution, - }, - }), {}) + ctx.wantedLockfile.packages = mapValues(({ dependencies, optionalDependencies, resolution }) => ({ + // These fields are needed to avoid losing information of the locked dependencies if these fields are not broken + // If these fields are broken, they will also be regenerated + dependencies, + optionalDependencies, + resolution, + }), ctx.wantedLockfile.packages) } let { @@ -841,30 +836,27 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => { } ) if (!opts.include.optionalDependencies || !opts.include.devDependencies || !opts.include.dependencies) { - for (const projectId of Object.keys(linkedDependenciesByProjectId ?? {})) { - linkedDependenciesByProjectId[projectId] = linkedDependenciesByProjectId[projectId].filter((linkedDep) => + linkedDependenciesByProjectId = mapValues( + (linkedDeps) => linkedDeps.filter((linkedDep) => !( linkedDep.dev && !opts.include.devDependencies || linkedDep.optional && !opts.include.optionalDependencies || !linkedDep.dev && !linkedDep.optional && !opts.include.dependencies - ) - ) - } + )), + linkedDependenciesByProjectId ?? {} + ) for (const { id, manifest } of projects) { - dependenciesByProjectId[id] = fromPairs( - Object.entries(dependenciesByProjectId[id]) - .filter(([, depPath]) => { - const dep = dependenciesGraph[depPath] - if (!dep) return false - const isDev = Boolean(manifest.devDependencies?.[dep.name]) - const isOptional = Boolean(manifest.optionalDependencies?.[dep.name]) - return !( - isDev && !opts.include.devDependencies || - isOptional && !opts.include.optionalDependencies || - !isDev && !isOptional && !opts.include.dependencies - ) - }) - ) + dependenciesByProjectId[id] = pickBy((depPath) => { + const dep = dependenciesGraph[depPath] + if (!dep) return false + const isDev = Boolean(manifest.devDependencies?.[dep.name]) + const isOptional = Boolean(manifest.optionalDependencies?.[dep.name]) + return !( + isDev && !opts.include.devDependencies || + isOptional && !opts.include.optionalDependencies || + !isDev && !isOptional && !opts.include.dependencies + ) + }, dependenciesByProjectId[id]) } } diff --git a/packages/core/src/install/link.ts b/packages/core/src/install/link.ts index 0ec4218e48..8c5182df54 100644 --- a/packages/core/src/install/link.ts +++ b/packages/core/src/install/link.ts @@ -33,6 +33,8 @@ import equals from 'ramda/src/equals' import isEmpty from 'ramda/src/isEmpty' import difference from 'ramda/src/difference' import omit from 'ramda/src/omit' +import pick from 'ramda/src/pick' +import pickBy from 'ramda/src/pickBy' import props from 'ramda/src/props' import { ImporterToUpdate } from './index' @@ -211,10 +213,10 @@ export async function linkPackages ( } } } - const projects = projectIds.reduce((acc, projectId) => { - acc[projectId] = opts.wantedLockfile.importers[projectId] - return acc - }, opts.currentLockfile.importers) + const projects = { + ...opts.currentLockfile.importers, + ...pick(projectIds, opts.wantedLockfile.importers), + } currentLockfile = filterLockfileByImporters( { ...opts.wantedLockfile, @@ -454,26 +456,20 @@ async function linkAllModules ( await Promise.all( depNodes .map(async ({ children, optionalDependencies, name, modules }) => { - const childrenToLink = opts.optional + const childrenToLink: Record = opts.optional ? children - : Object.keys(children) - .reduce((nonOptionalChildren, childAlias) => { - if (!optionalDependencies.has(childAlias)) { - nonOptionalChildren[childAlias] = children[childAlias] - } - return nonOptionalChildren - }, {}) + : pickBy((_, childAlias) => !optionalDependencies.has(childAlias), children) await Promise.all( Object.entries(childrenToLink) .map(async ([childAlias, childDepPath]) => { if (childDepPath.startsWith('link:')) { - await limitLinking(async () => symlinkDependency(path.resolve(opts.lockfileDir, childDepPath.slice(5)), modules, childAlias)) + await limitLinking(() => symlinkDependency(path.resolve(opts.lockfileDir, childDepPath.slice(5)), modules, childAlias)) return } const pkg = depGraph[childDepPath] if (!pkg || !pkg.installable && pkg.optional || childAlias === name) return - await limitLinking(async () => symlinkDependency(pkg.dir, modules, childAlias)) + await limitLinking(() => symlinkDependency(pkg.dir, modules, childAlias)) }) ) }) diff --git a/packages/dependencies-hierarchy/src/index.ts b/packages/dependencies-hierarchy/src/index.ts index 5484cf1e00..80acdaf060 100644 --- a/packages/dependencies-hierarchy/src/index.ts +++ b/packages/dependencies-hierarchy/src/index.ts @@ -141,13 +141,13 @@ async function dependenciesHierarchyForPackage ( for (const dependenciesField of DEPENDENCIES_FIELDS.sort().filter(dependenciedField => opts.include[dependenciedField])) { const topDeps = currentLockfile.importers[importerId][dependenciesField] ?? {} result[dependenciesField] = [] - Object.keys(topDeps).forEach((alias) => { + Object.entries(topDeps).forEach(([alias, ref]) => { const { packageInfo, packageAbsolutePath } = getPkgInfo({ alias, currentPackages: currentLockfile.packages ?? {}, lockfileDir: opts.lockfileDir, modulesDir, - ref: topDeps[alias], + ref, registries: opts.registries, skipped: opts.skipped, wantedPackages: wantedLockfile.packages ?? {}, @@ -158,7 +158,7 @@ async function dependenciesHierarchyForPackage ( if ((opts.search != null) && !matchedSearched) return newEntry = packageInfo } else { - const relativeId = refToRelative(topDeps[alias], alias) + const relativeId = refToRelative(ref, alias) if (relativeId) { const dependencies = getChildrenTree([relativeId], relativeId) if (dependencies.length > 0) { @@ -273,14 +273,14 @@ function getTreeHelper ( const peers = new Set(Object.keys(opts.currentPackages[parentId].peerDependencies ?? {})) - Object.keys(deps).forEach((alias) => { + Object.entries(deps).forEach(([alias, ref]) => { const { packageInfo, packageAbsolutePath } = getPkgInfo({ alias, currentPackages: opts.currentPackages, lockfileDir: opts.lockfileDir, modulesDir: opts.modulesDir, peers, - ref: deps[alias], + ref, registries: opts.registries, skipped: opts.skipped, wantedPackages: opts.wantedPackages, @@ -296,7 +296,7 @@ function getTreeHelper ( } else { let dependencies: PackageNode[] | undefined - const relativeId = refToRelative(deps[alias], alias) as string // we know for sure that relative is not null if pkgPath is not null + const relativeId = refToRelative(ref, alias) as string // we know for sure that relative is not null if pkgPath is not null circular = keypath.includes(relativeId) if (circular) { diff --git a/packages/dependency-path/src/index.ts b/packages/dependency-path/src/index.ts index 7ff63d7fcf..6167554750 100644 --- a/packages/dependency-path/src/index.ts +++ b/packages/dependency-path/src/index.ts @@ -76,7 +76,7 @@ export function relative ( export function refToRelative ( reference: string, pkgName: string -) { +): string | null { if (reference.startsWith('link:')) { return null } diff --git a/packages/exportable-manifest/package.json b/packages/exportable-manifest/package.json index e71a86ae3f..3b05b2a34c 100644 --- a/packages/exportable-manifest/package.json +++ b/packages/exportable-manifest/package.json @@ -36,6 +36,7 @@ "@pnpm/error": "workspace:*", "@pnpm/read-project-manifest": "workspace:*", "@pnpm/types": "workspace:*", + "p-map-values": "^1.0.0", "ramda": "npm:@pnpm/ramda@0.28.1" }, "funding": "https://opencollective.com/pnpm", diff --git a/packages/exportable-manifest/src/index.ts b/packages/exportable-manifest/src/index.ts index 90615a62d9..439daa93e3 100644 --- a/packages/exportable-manifest/src/index.ts +++ b/packages/exportable-manifest/src/index.ts @@ -2,8 +2,8 @@ import path from 'path' import { PnpmError } from '@pnpm/error' import { tryReadProjectManifest } from '@pnpm/read-project-manifest' import { Dependencies, ProjectManifest } from '@pnpm/types' -import fromPairs from 'ramda/src/fromPairs' import omit from 'ramda/src/omit' +import pMapValues from 'p-map-values' import { overridePublishConfig } from './overridePublishConfig' const PREPUBLISH_SCRIPTS = [ @@ -45,16 +45,15 @@ export async function createExportableManifest ( return publishManifest } -async function makePublishDependencies (dir: string, dependencies: Dependencies | undefined, modulesDir?: string) { +async function makePublishDependencies ( + dir: string, + dependencies: Dependencies | undefined, + modulesDir?: string +): Promise { if (dependencies == null) return dependencies - const publishDependencies: Dependencies = fromPairs( - await Promise.all( - Object.entries(dependencies) - .map(async ([depName, depSpec]) => [ - depName, - await makePublishDependency(depName, depSpec, dir, modulesDir), - ]) - ) as any, // eslint-disable-line + const publishDependencies = await pMapValues( + (depSpec, depName) => makePublishDependency(depName, depSpec, dir, modulesDir), + dependencies ) return publishDependencies } diff --git a/packages/filter-lockfile/src/filterImporter.ts b/packages/filter-lockfile/src/filterImporter.ts index 0f7322a3e2..544dff9840 100644 --- a/packages/filter-lockfile/src/filterImporter.ts +++ b/packages/filter-lockfile/src/filterImporter.ts @@ -4,7 +4,7 @@ import { DependenciesField } from '@pnpm/types' export function filterImporter ( importer: ProjectSnapshot, include: { [dependenciesField in DependenciesField]: boolean } -) { +): ProjectSnapshot { return { dependencies: !include.dependencies ? {} : importer.dependencies ?? {}, devDependencies: !include.devDependencies ? {} : importer.devDependencies ?? {}, diff --git a/packages/filter-lockfile/src/filterLockfile.ts b/packages/filter-lockfile/src/filterLockfile.ts index 869d9efa99..e68f9e9bb6 100644 --- a/packages/filter-lockfile/src/filterLockfile.ts +++ b/packages/filter-lockfile/src/filterLockfile.ts @@ -1,6 +1,7 @@ import { Lockfile } from '@pnpm/lockfile-types' import { DependenciesField } from '@pnpm/types' import fromPairs from 'ramda/src/fromPairs' +import mapValues from 'ramda/src/map' import { filterImporter } from './filterImporter' export function filterLockfile ( @@ -11,22 +12,19 @@ export function filterLockfile ( } ): Lockfile { let pairs = Object.entries(lockfile.packages ?? {}) - .filter(([depPath, pkg]) => !opts.skipped.has(depPath)) + .filter(([depPath]) => !opts.skipped.has(depPath)) if (!opts.include.dependencies) { - pairs = pairs.filter(([depPath, pkg]) => pkg.dev !== false || pkg.optional) + pairs = pairs.filter(([_, pkg]) => pkg.dev !== false || pkg.optional) } if (!opts.include.devDependencies) { - pairs = pairs.filter(([depPath, pkg]) => pkg.dev !== true) + pairs = pairs.filter(([_, pkg]) => pkg.dev !== true) } if (!opts.include.optionalDependencies) { - pairs = pairs.filter(([depPath, pkg]) => !pkg.optional) + pairs = pairs.filter(([_, pkg]) => !pkg.optional) } return { ...lockfile, - importers: Object.keys(lockfile.importers).reduce((acc, importerId) => { - acc[importerId] = filterImporter(lockfile.importers[importerId], opts.include) - return acc - }, {}), + importers: mapValues((importer) => filterImporter(importer, opts.include), lockfile.importers), packages: fromPairs(pairs), } } diff --git a/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts b/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts index c3702c517e..eeee19e113 100644 --- a/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts +++ b/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts @@ -9,6 +9,8 @@ import { logger } from '@pnpm/logger' import { packageIsInstallable } from '@pnpm/package-is-installable' import { DependenciesField } from '@pnpm/types' import * as dp from 'dependency-path' +import mapValues from 'ramda/src/map' +import pickBy from 'ramda/src/pickBy' import unnest from 'ramda/src/unnest' import { filterImporter } from './filterImporter' @@ -51,18 +53,16 @@ export function filterLockfileByImportersAndEngine ( }) : {} - const importers = importerIds.reduce((acc, importerId) => { - acc[importerId] = filterImporter(lockfile.importers[importerId], opts.include) - if (acc[importerId].optionalDependencies != null) { - for (const depName of Object.keys(acc[importerId].optionalDependencies ?? {})) { - const depPath = dp.refToRelative(acc[importerId].optionalDependencies![depName], depName) - if (depPath && !packages[depPath]) { - delete acc[importerId].optionalDependencies![depName] - } - } + const importers = mapValues((importer) => { + const newImporter = filterImporter(importer, opts.include) + if (newImporter.optionalDependencies != null) { + newImporter.optionalDependencies = pickBy((ref, depName) => { + const depPath = dp.refToRelative(ref, depName) + return !depPath || packages[depPath] != null + }, newImporter.optionalDependencies) } - return acc - }, { ...lockfile.importers }) + return newImporter + }, lockfile.importers) return { lockfile: { diff --git a/packages/filter-lockfile/test/filterByImportersAndEngine.ts b/packages/filter-lockfile/test/filterByImportersAndEngine.ts index e4c3fc1857..8dcee6ca9b 100644 --- a/packages/filter-lockfile/test/filterByImportersAndEngine.ts +++ b/packages/filter-lockfile/test/filterByImportersAndEngine.ts @@ -143,6 +143,8 @@ test('filterByImportersAndEngine(): skip packages that are not installable', () dependencies: { 'project-2-prod-dep': '1.0.0', }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { 'project-2-prod-dep': '^1.0.0', }, @@ -322,6 +324,8 @@ test('filterByImportersAndEngine(): filter the packages that set os and cpu', () dependencies: { 'project-2-prod-dep': '1.0.0', }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { 'project-2-prod-dep': '^1.0.0', }, @@ -490,6 +494,8 @@ test('filterByImportersAndEngine(): filter the packages that set libc', () => { dependencies: { 'project-2-prod-dep': '1.0.0', }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { 'project-2-prod-dep': '^1.0.0', }, @@ -547,10 +553,8 @@ test('filterByImportersAndEngine(): includes linked packages', () => { dependencies: { 'project-2': 'link:project-2', }, - devDependencies: { - }, - optionalDependencies: { - }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { 'project-2': '^1.0.0', }, @@ -607,10 +611,8 @@ test('filterByImportersAndEngine(): includes linked packages', () => { dependencies: { 'project-2': 'link:project-2', }, - devDependencies: { - }, - optionalDependencies: { - }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { 'project-2': '^1.0.0', }, @@ -620,6 +622,8 @@ test('filterByImportersAndEngine(): includes linked packages', () => { 'project-3': 'link:project-3', foo: '1.0.0', }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { foo: '^1.0.0', }, @@ -628,6 +632,8 @@ test('filterByImportersAndEngine(): includes linked packages', () => { dependencies: { bar: '1.0.0', }, + devDependencies: {}, + optionalDependencies: {}, specifiers: { bar: '^1.0.0', }, diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index 5cca0385f6..9273c1e2e7 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -65,6 +65,7 @@ import fromPairs from 'ramda/src/fromPairs' import isEmpty from 'ramda/src/isEmpty' import omit from 'ramda/src/omit' import pick from 'ramda/src/pick' +import pickBy from 'ramda/src/pickBy' import props from 'ramda/src/props' import union from 'ramda/src/union' import realpathMissing from 'realpath-missing' @@ -639,12 +640,12 @@ async function linkRootPackages ( ...projectSnapshot.optionalDependencies, } return Promise.all( - Object.keys(allDeps) - .map(async (alias) => { - if (allDeps[alias].startsWith('link:')) { + Object.entries(allDeps) + .map(async ([alias, ref]) => { + if (ref.startsWith('link:')) { const isDev = Boolean(projectSnapshot.devDependencies?.[alias]) const isOptional = Boolean(projectSnapshot.optionalDependencies?.[alias]) - const packageDir = path.join(opts.projectDir, allDeps[alias].slice(5)) + const packageDir = path.join(opts.projectDir, ref.slice(5)) const linkedPackage = await (async () => { const importerId = getLockfileImporterId(opts.lockfileDir, packageDir) if (importerManifestsByImporterId[importerId]) { @@ -678,11 +679,11 @@ async function linkRootPackages ( const isDev = Boolean(projectSnapshot.devDependencies?.[alias]) const isOptional = Boolean(projectSnapshot.optionalDependencies?.[alias]) - const depPath = dp.refToRelative(allDeps[alias], alias) + const depPath = dp.refToRelative(ref, alias) if (depPath === null) return const pkgSnapshot = lockfile.packages?.[depPath] if (pkgSnapshot == null) return // this won't ever happen. Just making typescript happy - const pkgId = pkgSnapshot.id ?? dp.refToAbsolute(allDeps[alias], alias, opts.registries) ?? undefined + const pkgId = pkgSnapshot.id ?? dp.refToAbsolute(ref, alias, opts.registries) ?? undefined const pkgInfo = nameVerFromPkgSnapshot(depPath, pkgSnapshot) rootLogger.debug({ added: { @@ -769,15 +770,9 @@ async function linkAllBins ( return Promise.all( Object.values(depGraph) .map(async (depNode) => limitLinking(async () => { - const childrenToLink = opts.optional + const childrenToLink: Record = opts.optional ? depNode.children - : Object.keys(depNode.children) - .reduce((nonOptionalChildren, childAlias) => { - if (!depNode.optionalDependencies.has(childAlias)) { - nonOptionalChildren[childAlias] = depNode.children[childAlias] - } - return nonOptionalChildren - }, {}) + : pickBy((_, childAlias) => !depNode.optionalDependencies.has(childAlias), depNode.children) const binPath = path.join(depNode.dir, 'node_modules/.bin') const pkgSnapshots = props(Object.values(childrenToLink), depGraph) @@ -827,15 +822,9 @@ async function linkAllModules ( await Promise.all( depNodes .map(async (depNode) => { - const childrenToLink = opts.optional + const childrenToLink: Record = opts.optional ? depNode.children - : Object.keys(depNode.children) - .reduce((nonOptionalChildren, childAlias) => { - if (!depNode.optionalDependencies.has(childAlias)) { - nonOptionalChildren[childAlias] = depNode.children[childAlias] - } - return nonOptionalChildren - }, {}) + : pickBy((_, childAlias) => !depNode.optionalDependencies.has(childAlias), depNode.children) await Promise.all( Object.entries(childrenToLink) @@ -844,7 +833,7 @@ async function linkAllModules ( if (alias === depNode.name) { return } - await limitLinking(async () => symlinkDependency(pkgDir, depNode.modules, alias)) + await limitLinking(() => symlinkDependency(pkgDir, depNode.modules, alias)) }) ) }) diff --git a/packages/headless/src/lockfileToDepGraph.ts b/packages/headless/src/lockfileToDepGraph.ts index aa68485999..af811ac309 100644 --- a/packages/headless/src/lockfileToDepGraph.ts +++ b/packages/headless/src/lockfileToDepGraph.ts @@ -35,7 +35,7 @@ export interface DependenciesGraphNode { fetchingFiles: () => Promise finishing: () => Promise dir: string - children: { [alias: string]: string } + children: Record optionalDependencies: Set optional: boolean depPath: string // this option is only needed for saving pendingBuild when running with --ignore-scripts flag @@ -96,9 +96,8 @@ export async function lockfileToDepGraph ( if (lockfile.packages != null) { const pkgSnapshotByLocation = {} await Promise.all( - Object.keys(lockfile.packages).map(async (depPath) => { + Object.entries(lockfile.packages).map(async ([depPath, pkgSnapshot]) => { if (opts.skipped.has(depPath)) return - const pkgSnapshot = lockfile.packages![depPath] // TODO: optimize. This info can be already returned by pkgSnapshotToResolution() const { name: pkgName, version: pkgVersion } = nameVerFromPkgSnapshot(depPath, pkgSnapshot) const modules = path.join(opts.virtualStoreDir, dp.depPathToFilename(depPath), 'node_modules') @@ -194,7 +193,7 @@ export async function lockfileToDepGraph ( storeDir: opts.storeDir, virtualStoreDir: opts.virtualStoreDir, } - for (const dir of Object.keys(graph)) { + for (const [dir, node] of Object.entries(graph)) { const pkgSnapshot = pkgSnapshotByLocation[dir] const allDeps = { ...pkgSnapshot.dependencies, @@ -202,7 +201,7 @@ export async function lockfileToDepGraph ( } const peerDeps = pkgSnapshot.peerDependencies ? new Set(Object.keys(pkgSnapshot.peerDependencies)) : null - graph[dir].children = await getChildrenPaths(ctx, allDeps, peerDeps, '.') + node.children = getChildrenPaths(ctx, allDeps, peerDeps, '.') } for (const importerId of opts.importerIds) { const projectSnapshot = lockfile.importers[importerId] @@ -211,13 +210,13 @@ export async function lockfileToDepGraph ( ...(opts.include.dependencies ? projectSnapshot.dependencies : {}), ...(opts.include.optionalDependencies ? projectSnapshot.optionalDependencies : {}), } - directDependenciesByImporterId[importerId] = await getChildrenPaths(ctx, rootDeps, null, importerId) + directDependenciesByImporterId[importerId] = getChildrenPaths(ctx, rootDeps, null, importerId) } } return { graph, directDependenciesByImporterId } } -async function getChildrenPaths ( +function getChildrenPaths ( ctx: { graph: DependenciesGraph force: boolean @@ -235,13 +234,13 @@ async function getChildrenPaths ( importerId: string ) { const children: { [alias: string]: string } = {} - for (const alias of Object.keys(allDeps)) { - const childDepPath = dp.refToAbsolute(allDeps[alias], alias, ctx.registries) + for (const [alias, ref] of Object.entries(allDeps)) { + const childDepPath = dp.refToAbsolute(ref, alias, ctx.registries) if (childDepPath === null) { - children[alias] = path.resolve(ctx.lockfileDir, importerId, allDeps[alias].slice(5)) + children[alias] = path.resolve(ctx.lockfileDir, importerId, ref.slice(5)) continue } - const childRelDepPath = dp.refToRelative(allDeps[alias], alias) as string + const childRelDepPath = dp.refToRelative(ref, alias) as string const childPkgSnapshot = ctx.pkgSnapshotsByDepPaths[childRelDepPath] if (ctx.graph[childRelDepPath]) { children[alias] = ctx.graph[childRelDepPath].dir @@ -249,8 +248,8 @@ async function getChildrenPaths ( if (ctx.skipped.has(childRelDepPath)) continue const pkgName = nameVerFromPkgSnapshot(childRelDepPath, childPkgSnapshot).name children[alias] = path.join(ctx.virtualStoreDir, dp.depPathToFilename(childRelDepPath), 'node_modules', pkgName) - } else if (allDeps[alias].indexOf('file:') === 0) { - children[alias] = path.resolve(ctx.lockfileDir, allDeps[alias].slice(5)) + } else if (ref.indexOf('file:') === 0) { + children[alias] = path.resolve(ctx.lockfileDir, ref.slice(5)) } else if (!ctx.skipped.has(childRelDepPath) && ((peerDeps == null) || !peerDeps.has(alias))) { throw new Error(`${childRelDepPath} not found in ${WANTED_LOCKFILE}`) } diff --git a/packages/hoist/src/index.ts b/packages/hoist/src/index.ts index 5a2463859e..f3091c3db2 100644 --- a/packages/hoist/src/index.ts +++ b/packages/hoist/src/index.ts @@ -12,6 +12,7 @@ import { symlinkDependency } from '@pnpm/symlink-dependency' import { HoistedDependencies } from '@pnpm/types' import { lexCompare } from '@pnpm/util.lex-comparator' import * as dp from 'dependency-path' +import mapObjIndexed from 'ramda/src/mapObjIndexed' const hoistLogger = logger('hoist') @@ -128,10 +129,7 @@ async function getDependencies ( ...pkgSnapshot.optionalDependencies, } deps.push({ - children: Object.entries(allDeps).reduce((children, [alias, ref]) => { - children[alias] = dp.refToRelative(ref, alias) - return children - }, {}), + children: mapObjIndexed(dp.refToRelative, allDeps) as Record, depPath, depth, }) @@ -153,14 +151,14 @@ async function getDependencies ( } export interface Dependency { - children: { [alias: string]: string } + children: Record depPath: string depth: number } async function hoistGraph ( depNodes: Dependency[], - currentSpecifiers: { [alias: string]: string }, + currentSpecifiers: Record, opts: { getAliasHoistType: GetAliasHoistType } diff --git a/packages/license-scanner/package.json b/packages/license-scanner/package.json index 0bed5baa23..d1cb925f84 100644 --- a/packages/license-scanner/package.json +++ b/packages/license-scanner/package.json @@ -49,7 +49,8 @@ "dependency-path": "workspace:*", "load-json-file": "^6.2.0", "p-limit": "^3.1.0", - "path-absolute": "^1.0.1" + "path-absolute": "^1.0.1", + "ramda": "npm:@pnpm/ramda@0.28.1" }, "devDependencies": { "@pnpm/constants": "workspace:*", diff --git a/packages/license-scanner/src/lockfileToLicenseNodeTree.ts b/packages/license-scanner/src/lockfileToLicenseNodeTree.ts index 76238422ff..99eb6f36ec 100644 --- a/packages/license-scanner/src/lockfileToLicenseNodeTree.ts +++ b/packages/license-scanner/src/lockfileToLicenseNodeTree.ts @@ -7,6 +7,7 @@ import { } from '@pnpm/lockfile-walker' import { DependenciesField, Registries } from '@pnpm/types' import { getPkgInfo } from './getPkgInfo' +import mapValues from 'ramda/src/map' export interface LicenseNode { name?: string @@ -154,10 +155,6 @@ export async function lockfileToLicenseNodeTree ( return licenseNodeTree } -function toRequires (licenseNodesByDepName: Record) { - const requires = {} - for (const subdepName of Object.keys(licenseNodesByDepName)) { - requires[subdepName] = licenseNodesByDepName[subdepName].version - } - return requires +function toRequires (licenseNodesByDepName: Record): Record { + return mapValues((licenseNode) => licenseNode.version!, licenseNodesByDepName) } diff --git a/packages/lockfile-file/src/sortLockfileKeys.ts b/packages/lockfile-file/src/sortLockfileKeys.ts index 382ff5435b..b148fbc9d3 100644 --- a/packages/lockfile-file/src/sortLockfileKeys.ts +++ b/packages/lockfile-file/src/sortLockfileKeys.ts @@ -61,8 +61,8 @@ export function sortLockfileKeys (lockfile: LockfileFile) { const compareRootKeys = compareWithPriority.bind(null, ROOT_KEYS_ORDER) if (lockfile.importers != null) { lockfile.importers = sortKeys(lockfile.importers) - for (const importerId of Object.keys(lockfile.importers)) { - lockfile.importers[importerId] = sortKeys(lockfile.importers[importerId], { + for (const [importerId, importer] of Object.entries(lockfile.importers)) { + lockfile.importers[importerId] = sortKeys(importer, { compare: compareRootKeys, deep: true, }) @@ -70,8 +70,8 @@ export function sortLockfileKeys (lockfile: LockfileFile) { } if (lockfile.packages != null) { lockfile.packages = sortKeys(lockfile.packages) - for (const pkgId of Object.keys(lockfile.packages)) { - lockfile.packages[pkgId] = sortKeys(lockfile.packages[pkgId], { + for (const [pkgId, pkg] of Object.entries(lockfile.packages)) { + lockfile.packages[pkgId] = sortKeys(pkg, { compare: compareWithPriority.bind(null, ORDERED_KEYS), deep: true, }) diff --git a/packages/lockfile-file/src/write.ts b/packages/lockfile-file/src/write.ts index d64565ddc8..3ffebe189c 100644 --- a/packages/lockfile-file/src/write.ts +++ b/packages/lockfile-file/src/write.ts @@ -7,8 +7,9 @@ import rimraf from '@zkochan/rimraf' import * as dp from 'dependency-path' import yaml from 'js-yaml' import equals from 'ramda/src/equals' -import fromPairs from 'ramda/src/fromPairs' +import pickBy from 'ramda/src/pickBy' import isEmpty from 'ramda/src/isEmpty' +import mapValues from 'ramda/src/map' import writeFileAtomicCB from 'write-file-atomic' import { lockfileLogger as logger } from './logger' import { sortLockfileKeys } from './sortLockfileKeys' @@ -118,8 +119,7 @@ export function normalizeLockfile (lockfile: Lockfile, opts: NormalizeLockfileOp } else { lockfileToSave = { ...lockfile, - importers: Object.keys(lockfile.importers).reduce((acc, alias) => { - const importer = lockfile.importers[alias] + importers: mapValues((importer) => { const normalizedImporter: Partial = {} if (!isEmpty(importer.specifiers ?? {}) || opts.includeEmptySpecifiersField) { normalizedImporter['specifiers'] = importer.specifiers ?? {} @@ -135,9 +135,8 @@ export function normalizeLockfile (lockfile: Lockfile, opts: NormalizeLockfileOp if (importer.publishDirectory) { normalizedImporter.publishDirectory = importer.publishDirectory } - acc[alias] = normalizedImporter - return acc - }, {}), + return normalizedImporter as ProjectSnapshot + }, lockfile.importers), } if (isEmpty(lockfileToSave.packages) || (lockfileToSave.packages == null)) { delete lockfileToSave.packages @@ -168,7 +167,7 @@ export function normalizeLockfile (lockfile: Lockfile, opts: NormalizeLockfileOp return lockfileToSave } -function pruneTime (time: Record, importers: Record) { +function pruneTime (time: Record, importers: Record): Record { const rootDepPaths = new Set() for (const importer of Object.values(importers)) { for (const depType of DEPENDENCIES_FIELDS) { @@ -184,7 +183,7 @@ function pruneTime (time: Record, importers: Record rootDepPaths.has(depPath))) + return pickBy((t, depPath) => rootDepPaths.has(depPath), time) } export async function writeLockfiles ( diff --git a/packages/lockfile-to-pnp/src/index.ts b/packages/lockfile-to-pnp/src/index.ts index 4b0e6c8b84..0012ca46dd 100644 --- a/packages/lockfile-to-pnp/src/index.ts +++ b/packages/lockfile-to-pnp/src/index.ts @@ -40,8 +40,7 @@ export function lockfileToPackageRegistry ( } ): PackageRegistry { const packageRegistry = new Map() - for (const importerId of Object.keys(lockfile.importers)) { - const importer = lockfile.importers[importerId] + for (const [importerId, importer] of Object.entries(lockfile.importers)) { if (importerId === '.') { const packageStore = new Map([ [ diff --git a/packages/lockfile-types/src/index.ts b/packages/lockfile-types/src/index.ts index b2d62090b8..39a184841e 100644 --- a/packages/lockfile-types/src/index.ts +++ b/packages/lockfile-types/src/index.ts @@ -111,6 +111,4 @@ export type PackageBin = string | { [name: string]: string } * "foo": "registry.npmjs.org/foo/1.0.1" * } */ -export interface ResolvedDependencies { - [depName: string]: string -} +export type ResolvedDependencies = Record diff --git a/packages/make-dedicated-lockfile/src/index.ts b/packages/make-dedicated-lockfile/src/index.ts index 2c50665e85..272c5e5f6a 100644 --- a/packages/make-dedicated-lockfile/src/index.ts +++ b/packages/make-dedicated-lockfile/src/index.ts @@ -10,7 +10,7 @@ import { import { pruneSharedLockfile } from '@pnpm/prune-lockfile' import { readProjectManifest } from '@pnpm/read-project-manifest' import { DEPENDENCIES_FIELDS } from '@pnpm/types' -import fromPairs from 'ramda/src/fromPairs' +import pickBy from 'ramda/src/pickBy' import renameOverwrite from 'rename-overwrite' export async function makeDedicatedLockfile (lockfileDir: string, projectDir: string) { @@ -77,10 +77,7 @@ function projectSnapshotWithoutLinkedDeps (projectSnapshot: ProjectSnapshot) { } for (const depField of DEPENDENCIES_FIELDS) { if (projectSnapshot[depField] == null) continue - newProjectSnapshot[depField] = fromPairs( - Object.entries(projectSnapshot[depField]!) - .filter(([depName, depVersion]) => !depVersion.startsWith('link:')) - ) + newProjectSnapshot[depField] = pickBy((depVersion) => !depVersion.startsWith('link:'), projectSnapshot[depField]) } return newProjectSnapshot } diff --git a/packages/modules-cleaner/src/prune.ts b/packages/modules-cleaner/src/prune.ts index 3d4e913a55..62badbfa94 100644 --- a/packages/modules-cleaner/src/prune.ts +++ b/packages/modules-cleaner/src/prune.ts @@ -212,13 +212,12 @@ function getPkgsDepPaths ( registries: Registries, packages: PackageSnapshots, skipped: Set -): { [depPath: string]: string } { - const pkgIdsByDepPath = {} - for (const depPath of Object.keys(packages)) { - if (skipped.has(depPath)) continue - pkgIdsByDepPath[depPath] = packageIdFromSnapshot(depPath, packages[depPath], registries) - } - return pkgIdsByDepPath +): Record { + return Object.entries(packages).reduce((acc, [depPath, pkg]) => { + if (skipped.has(depPath)) return acc + acc[depPath] = packageIdFromSnapshot(depPath, pkg, registries) + return acc + }, {}) } function getPkgsDepPathsOwnedOnlyByImporters ( @@ -242,7 +241,10 @@ function getPkgsDepPathsOwnedOnlyByImporters ( include, skipped, }) - const packagesOfSelectedOnly = pickAll(difference(Object.keys(selected.packages!), Object.keys(other.packages!)), selected.packages!) as PackageSnapshots + const packagesOfSelectedOnly = pickAll( + difference(Object.keys(selected.packages!), Object.keys(other.packages!)), + selected.packages! + ) as PackageSnapshots return getPkgsDepPaths(registries, packagesOfSelectedOnly, skipped) } diff --git a/packages/modules-yaml/package.json b/packages/modules-yaml/package.json index badf805e7f..e9fb6fed94 100644 --- a/packages/modules-yaml/package.json +++ b/packages/modules-yaml/package.json @@ -33,12 +33,14 @@ "dependencies": { "@pnpm/types": "workspace:*", "is-windows": "^1.0.2", + "ramda": "npm:@pnpm/ramda@0.28.1", "read-yaml-file": "^2.1.0", "write-yaml-file": "^4.2.0" }, "devDependencies": { "@pnpm/modules-yaml": "workspace:*", "@types/is-windows": "^1.0.0", + "@types/ramda": "0.28.15", "tempy": "^1.0.1" }, "funding": "https://opencollective.com/pnpm", diff --git a/packages/modules-yaml/src/index.ts b/packages/modules-yaml/src/index.ts index e351cb32ee..ffc62241c0 100644 --- a/packages/modules-yaml/src/index.ts +++ b/packages/modules-yaml/src/index.ts @@ -1,6 +1,8 @@ import path from 'path' import { DependenciesField, HoistedDependencies, Registries } from '@pnpm/types' import readYamlFile from 'read-yaml-file' +import fromPairs from 'ramda/src/fromPairs' +import mapValues from 'ramda/src/map' import isWindows from 'is-windows' import writeYamlFile from 'write-yaml-file' @@ -53,13 +55,10 @@ export async function readModulesManifest (modulesDir: string): Promise fromPairs(aliases.map((alias) => [alias, 'public'])), + modules.hoistedAliases + ) } break case false: diff --git a/packages/normalize-registries/package.json b/packages/normalize-registries/package.json index 92ecaed13e..fbebd6ebff 100644 --- a/packages/normalize-registries/package.json +++ b/packages/normalize-registries/package.json @@ -27,12 +27,14 @@ }, "dependencies": { "@pnpm/types": "workspace:*", - "normalize-registry-url": "2.0.0" + "normalize-registry-url": "2.0.0", + "ramda": "npm:@pnpm/ramda@0.28.1" }, "homepage": "https://github.com/pnpm/pnpm/blob/main/packages/normalize-registries#readme", "funding": "https://opencollective.com/pnpm", "devDependencies": { - "@pnpm/normalize-registries": "workspace:*" + "@pnpm/normalize-registries": "workspace:*", + "@types/ramda": "0.28.15" }, "exports": { ".": "./lib/index.js" diff --git a/packages/normalize-registries/src/index.ts b/packages/normalize-registries/src/index.ts index b1997fe4c7..87c2820fae 100644 --- a/packages/normalize-registries/src/index.ts +++ b/packages/normalize-registries/src/index.ts @@ -1,18 +1,14 @@ import { Registries } from '@pnpm/types' import normalizeRegistryUrl from 'normalize-registry-url' +import mapValues from 'ramda/src/map' export const DEFAULT_REGISTRIES = { default: 'https://registry.npmjs.org/', } -export function normalizeRegistries (registries?: { [scope: string]: string }): Registries { +export function normalizeRegistries (registries?: Record): Registries { if (registries == null) return DEFAULT_REGISTRIES - - const normalizeRegistries = {} - for (const scope of Object.keys(registries)) { - normalizeRegistries[scope] = normalizeRegistryUrl(registries[scope]) - } - + const normalizeRegistries = mapValues(normalizeRegistryUrl, registries) return { ...DEFAULT_REGISTRIES, ...normalizeRegistries, diff --git a/packages/package-requester/package.json b/packages/package-requester/package.json index 9e0225f9f2..faaa9ac8f9 100644 --- a/packages/package-requester/package.json +++ b/packages/package-requester/package.json @@ -53,6 +53,7 @@ "load-json-file": "^6.2.0", "p-defer": "^3.0.0", "p-limit": "^3.1.0", + "p-map-values": "^1.0.0", "p-queue": "^6.6.2", "path-temp": "^2.0.0", "promise-share": "^1.0.0", diff --git a/packages/package-requester/src/packageRequester.ts b/packages/package-requester/src/packageRequester.ts index 9fc9864f43..0024b80a3e 100644 --- a/packages/package-requester/src/packageRequester.ts +++ b/packages/package-requester/src/packageRequester.ts @@ -41,6 +41,7 @@ import { } from '@pnpm/store-controller-types' import { DependencyManifest } from '@pnpm/types' import { depPathToFilename } from 'dependency-path' +import pMapValues from 'p-map-values' import PQueue from 'p-queue' import loadJsonFile from 'load-json-file' import pDefer from 'p-defer' @@ -538,26 +539,18 @@ Actual package in the store by the given integrity: ${pkgFilesIndex.name}@${pkgF let filesResult!: PackageFilesResponse if (!fetchedPackage.local) { - const filesIndex = fetchedPackage.filesIndex // Ideally, files wouldn't care about when integrity is calculated. // However, we can only rename the temp folder once we know the package name. // And we cannot rename the temp folder till we're calculating integrities. - const integrity: Record = {} - await Promise.all( - Object.keys(filesIndex) - .map(async (filename) => { - const { - checkedAt, - integrity: fileIntegrity, - } = await filesIndex[filename].writeResult - integrity[filename] = { - checkedAt, - integrity: fileIntegrity.toString(), // TODO: use the raw Integrity object - mode: filesIndex[filename].mode, - size: filesIndex[filename].size, - } - }) - ) + const integrity = await pMapValues(async ({ writeResult, mode, size }) => { + const { checkedAt, integrity } = await writeResult + return { + checkedAt, + integrity: integrity.toString(), // TODO: use the raw Integrity object + mode, + size, + } + }, fetchedPackage.filesIndex) if (opts.pkg.name && opts.pkg.version) { await writeFilesIndexFile(filesIndexFile, { pkg: opts.pkg, diff --git a/packages/parse-cli-args/src/index.ts b/packages/parse-cli-args/src/index.ts index 8bc387fe5e..22a0acbdf7 100644 --- a/packages/parse-cli-args/src/index.ts +++ b/packages/parse-cli-args/src/index.ts @@ -131,9 +131,9 @@ export async function parseCliArgs ( } if (opts.renamedOptions != null) { - for (const cliOption of Object.keys(options)) { + for (const [cliOption, optionValue] of Object.entries(options)) { if (opts.renamedOptions[cliOption]) { - options[opts.renamedOptions[cliOption]] = options[cliOption] + options[opts.renamedOptions[cliOption]] = optionValue delete options[cliOption] } } diff --git a/packages/pkgs-graph/src/index.ts b/packages/pkgs-graph/src/index.ts index 8b73adc581..cca11114f7 100644 --- a/packages/pkgs-graph/src/index.ts +++ b/packages/pkgs-graph/src/index.ts @@ -1,6 +1,7 @@ import path from 'path' import npa from '@pnpm/npm-package-arg' import { resolveWorkspaceRange } from '@pnpm/resolve-workspace-range' +import mapValues from 'ramda/src/map' export interface Manifest { name?: string @@ -30,20 +31,15 @@ export function createPkgGraph (pkgs: Array, opts?: { ignoreDevDeps?: boolean linkWorkspacePackages?: boolean }): { - graph: { [id: string]: PackageNode } + graph: Record> unmatched: Array<{ pkgName: string, range: string }> } { const pkgMap = createPkgMap(pkgs) const unmatched: Array<{ pkgName: string, range: string }> = [] - const graph = Object.entries(pkgMap) - .reduce((acc, [pkgSpec, pkg]) => { - acc[pkgSpec] = { - dependencies: createNode(pkg), - package: pkg, - } - return acc - }, {}) - + const graph = mapValues((pkg) => ({ + dependencies: createNode(pkg), + package: pkg, + }), pkgMap) as Record> return { graph, unmatched } function createNode (pkg: Package): string[] { @@ -110,9 +106,7 @@ export function createPkgGraph (pkgs: Array, opts?: { } } -function createPkgMap (pkgs: Package[]): { - [pkgId: string]: Package -} { +function createPkgMap (pkgs: Package[]): Record { const pkgMap = {} for (const pkg of pkgs) { pkgMap[pkg.dir] = pkg diff --git a/packages/plugin-commands-installation/src/import/index.ts b/packages/plugin-commands-installation/src/import/index.ts index 32f9dd59e0..3525ce1fd8 100644 --- a/packages/plugin-commands-installation/src/import/index.ts +++ b/packages/plugin-commands-installation/src/import/index.ts @@ -16,6 +16,8 @@ import { logger } from '@pnpm/logger' import { sequenceGraph } from '@pnpm/sort-packages' import rimraf from '@zkochan/rimraf' import loadJsonFile from 'load-json-file' +import fromPairs from 'ramda/src/fromPairs' +import mapValues from 'ramda/src/map' import renderHelp from 'render-help' import { parse as parseYarnLock } from '@yarnpkg/lockfile' import * as yarnCore from '@yarnpkg/core' @@ -223,18 +225,11 @@ async function readNpmLockfile (dir: string) { throw new PnpmError('NPM_LOCKFILE_NOT_FOUND', 'No package-lock.json or npm-shrinkwrap.json found') } -function getPreferredVersions ( - versionsByPackageNames: { - [packageName: string]: Set - } -) { - const preferredVersions = {} - for (const packageName of Object.keys(versionsByPackageNames)) { - preferredVersions[packageName] = Array.from(versionsByPackageNames[packageName]).reduce((acc, version) => { - acc[version] = 'version' - return acc - }, {}) - } +function getPreferredVersions (versionsByPackageNames: Record>) { + const preferredVersions = mapValues( + (versions) => fromPairs(Array.from(versions).map((version) => [version, 'version'])), + versionsByPackageNames + ) return preferredVersions } @@ -245,14 +240,14 @@ function getAllVersionsByPackageNames ( } ) { if (npmPackageLock.dependencies == null) return - for (const packageName of Object.keys(npmPackageLock.dependencies)) { + for (const [packageName, { version }] of Object.entries(npmPackageLock.dependencies)) { if (!versionsByPackageNames[packageName]) { versionsByPackageNames[packageName] = new Set() } - versionsByPackageNames[packageName].add(npmPackageLock.dependencies[packageName].version) + versionsByPackageNames[packageName].add(version) } - for (const packageName of Object.keys(npmPackageLock.dependencies)) { - getAllVersionsByPackageNames(npmPackageLock.dependencies[packageName], versionsByPackageNames) + for (const dep of Object.values(npmPackageLock.dependencies)) { + getAllVersionsByPackageNames(dep, versionsByPackageNames) } } @@ -262,12 +257,12 @@ function getAllVersionsFromYarnLockFile ( [packageName: string]: Set } ) { - for (const packageName of Object.keys(yarnPackageLock)) { + for (const [packageName, { version }] of Object.entries(yarnPackageLock)) { const pkgName = packageName.substring(0, packageName.lastIndexOf('@')) if (!versionsByPackageNames[pkgName]) { versionsByPackageNames[pkgName] = new Set() } - versionsByPackageNames[pkgName].add(yarnPackageLock[packageName].version) + versionsByPackageNames[pkgName].add(version) } } diff --git a/packages/plugin-commands-installation/src/updateWorkspaceDependencies.ts b/packages/plugin-commands-installation/src/updateWorkspaceDependencies.ts index 514a5023e7..62f626297f 100644 --- a/packages/plugin-commands-installation/src/updateWorkspaceDependencies.ts +++ b/packages/plugin-commands-installation/src/updateWorkspaceDependencies.ts @@ -3,18 +3,22 @@ import { parseWantedDependency } from '@pnpm/parse-wanted-dependency' import { WorkspacePackages } from '@pnpm/resolver-base' import { IncludedDependencies, ProjectManifest } from '@pnpm/types' -export function updateToWorkspacePackagesFromManifest (manifest: ProjectManifest, include: IncludedDependencies, workspacePackages: WorkspacePackages) { +export function updateToWorkspacePackagesFromManifest ( + manifest: ProjectManifest, + include: IncludedDependencies, + workspacePackages: WorkspacePackages +) { const allDeps = { ...(include.devDependencies ? manifest.devDependencies : {}), ...(include.dependencies ? manifest.dependencies : {}), ...(include.optionalDependencies ? manifest.optionalDependencies : {}), } as Record - const updateSpecs = [] - for (const depName of Object.keys(allDeps)) { + const updateSpecs = Object.keys(allDeps).reduce((acc: string[], depName) => { if (workspacePackages[depName]) { - updateSpecs.push(`${depName}@workspace:*`) + acc.push(`${depName}@workspace:*`) } - } + return acc + }, []) return updateSpecs } diff --git a/packages/plugin-commands-store/src/storeStatus/index.ts b/packages/plugin-commands-store/src/storeStatus/index.ts index 52081696a3..cd2abbcc75 100644 --- a/packages/plugin-commands-store/src/storeStatus/index.ts +++ b/packages/plugin-commands-store/src/storeStatus/index.ts @@ -33,10 +33,9 @@ export async function storeStatus (maybeOpts: StoreStatusOptions) { }) if (!wantedLockfile) return [] - const pkgs = Object.keys(wantedLockfile.packages ?? {}) - .filter((depPath) => !skipped.has(depPath)) - .map((depPath) => { - const pkgSnapshot = wantedLockfile.packages![depPath] + const pkgs = Object.entries(wantedLockfile.packages ?? {}) + .filter(([depPath]) => !skipped.has(depPath)) + .map(([depPath, pkgSnapshot]) => { const id = packageIdFromSnapshot(depPath, pkgSnapshot, registries) return { depPath, diff --git a/packages/prune-lockfile/src/index.ts b/packages/prune-lockfile/src/index.ts index 7c5af9fcf4..59934216ec 100644 --- a/packages/prune-lockfile/src/index.ts +++ b/packages/prune-lockfile/src/index.ts @@ -62,9 +62,9 @@ export function pruneLockfile ( const lockfileOptionalDependencies: ResolvedDependencies = {} const lockfileDevDependencies: ResolvedDependencies = {} - Object.keys(lockfileSpecs).forEach((depName) => { + Object.entries(lockfileSpecs).forEach(([depName, spec]) => { if (!allDeps.includes(depName)) return - specifiers[depName] = lockfileSpecs[depName] + specifiers[depName] = spec if (importer.dependencies?.[depName]) { lockfileDependencies[depName] = importer.dependencies[depName] } else if (importer.optionalDependencies?.[depName]) { @@ -74,14 +74,14 @@ export function pruneLockfile ( } }) if (importer.dependencies != null) { - for (const dep of Object.keys(importer.dependencies)) { + for (const [alias, dep] of Object.entries(importer.dependencies)) { if ( - !lockfileDependencies[dep] && importer.dependencies[dep].startsWith('link:') && + !lockfileDependencies[alias] && dep.startsWith('link:') && // If the linked dependency was removed from package.json // then it is removed from pnpm-lock.yaml as well - !(lockfileSpecs[dep] && !allDeps[dep]) + !(lockfileSpecs[alias] && !allDeps[alias]) ) { - lockfileDependencies[dep] = importer.dependencies[dep] + lockfileDependencies[alias] = dep } } } diff --git a/packages/resolve-dependencies/src/getNonDevWantedDependencies.ts b/packages/resolve-dependencies/src/getNonDevWantedDependencies.ts index b1fce9b8d6..27a2ba9d1f 100644 --- a/packages/resolve-dependencies/src/getNonDevWantedDependencies.ts +++ b/packages/resolve-dependencies/src/getNonDevWantedDependencies.ts @@ -1,4 +1,5 @@ import { Dependencies, DependencyManifest, DependenciesMeta } from '@pnpm/types' +import pickBy from 'ramda/src/pickBy' export interface WantedDependency { alias: string @@ -31,20 +32,15 @@ function getWantedDependenciesFromGivenSet ( } ): WantedDependency[] { if (!deps) return [] - return Object.keys(deps).map((alias) => ({ + return Object.entries(deps).map(([alias, pref]) => ({ alias, dev: !!opts.devDependencies[alias], injected: opts.dependenciesMeta[alias]?.injected, optional: !!opts.optionalDependencies[alias], - pref: deps[alias], + pref, })) } -function getNotBundledDeps (bundledDeps: Set, deps: Dependencies) { - return Object.keys(deps) - .filter((depName) => !bundledDeps.has(depName)) - .reduce((notBundledDeps, depName) => { - notBundledDeps[depName] = deps[depName] - return notBundledDeps - }, {}) +function getNotBundledDeps (bundledDeps: Set, deps: Dependencies): Record { + return pickBy((_, depName) => !bundledDeps.has(depName), deps) } diff --git a/packages/resolve-dependencies/src/getWantedDependencies.ts b/packages/resolve-dependencies/src/getWantedDependencies.ts index 6a7de507f6..c19315ab75 100644 --- a/packages/resolve-dependencies/src/getWantedDependencies.ts +++ b/packages/resolve-dependencies/src/getWantedDependencies.ts @@ -68,8 +68,8 @@ function getWantedDependenciesFromGivenSet ( } ): WantedDependency[] { if (!deps) return [] - return Object.keys(deps).map((alias) => { - const pref = opts.updatePref(deps[alias]) + return Object.entries(deps).map(([alias, pref]) => { + const updatedPref = opts.updatePref(pref) let depType if (opts.optionalDependencies[alias] != null) depType = 'optional' else if (opts.dependencies[alias] != null) depType = 'prod' @@ -81,9 +81,9 @@ function getWantedDependenciesFromGivenSet ( injected: opts.dependenciesMeta[alias]?.injected, optional: depType === 'optional', nodeExecPath: opts.nodeExecPath ?? opts.dependenciesMeta[alias]?.node, - pinnedVersion: whichVersionIsPinned(deps[alias]), - pref, - raw: `${alias}@${pref}`, + pinnedVersion: whichVersionIsPinned(pref), + pref: updatedPref, + raw: `${alias}@${updatedPref}`, } }) } diff --git a/packages/resolve-dependencies/src/index.ts b/packages/resolve-dependencies/src/index.ts index 0df48f58a2..8eddd0ad82 100644 --- a/packages/resolve-dependencies/src/index.ts +++ b/packages/resolve-dependencies/src/index.ts @@ -409,9 +409,9 @@ function alignDependencyTypes (manifest: ProjectManifest, projectSnapshot: Proje // Aligning the dependency types in pnpm-lock.yaml for (const depType of DEPENDENCIES_FIELDS) { if (projectSnapshot[depType] == null) continue - for (const alias of Object.keys(projectSnapshot[depType] ?? {})) { + for (const [alias, ref] of Object.entries(projectSnapshot[depType] ?? {})) { if (depType === depTypesOfAliases[alias] || !depTypesOfAliases[alias]) continue - projectSnapshot[depTypesOfAliases[alias]][alias] = projectSnapshot[depType]![alias] + projectSnapshot[depTypesOfAliases[alias]][alias] = ref delete projectSnapshot[depType]![alias] } } diff --git a/packages/resolve-dependencies/src/resolveDependencies.ts b/packages/resolve-dependencies/src/resolveDependencies.ts index f07e5fb0f2..e05bf75c19 100644 --- a/packages/resolve-dependencies/src/resolveDependencies.ts +++ b/packages/resolve-dependencies/src/resolveDependencies.ts @@ -44,7 +44,7 @@ import exists from 'path-exists' import pDefer from 'p-defer' import pShare from 'promise-share' import isEmpty from 'ramda/src/isEmpty' -import fromPairs from 'ramda/src/fromPairs' +import pickBy from 'ramda/src/pickBy' import omit from 'ramda/src/omit' import zipWith from 'ramda/src/zipWith' import semver from 'semver' @@ -445,19 +445,20 @@ async function resolveDependenciesOfImporters ( } } -function filterMissingPeersFromPkgAddresses (pkgAddresses: PkgAddress[], currentParentPkgAliases: ParentPkgAliases, resolvedPeers: ResolvedPeers) { +function filterMissingPeersFromPkgAddresses ( + pkgAddresses: PkgAddress[], + currentParentPkgAliases: ParentPkgAliases, + resolvedPeers: ResolvedPeers +): PkgAddress[] { return pkgAddresses.map((pkgAddress) => ({ ...pkgAddress, - missingPeers: fromPairs( - Object.entries(pkgAddress.missingPeers || {}) - .filter(([peerName]) => { - if (!currentParentPkgAliases[peerName]) return true - if (currentParentPkgAliases[peerName] !== true) { - resolvedPeers[peerName] = currentParentPkgAliases[peerName] as PkgAddress - } - return false - }) - ), + missingPeers: pickBy((peer, peerName) => { + if (!currentParentPkgAliases[peerName]) return true + if (currentParentPkgAliases[peerName] !== true) { + resolvedPeers[peerName] = currentParentPkgAliases[peerName] as PkgAddress + } + return false + }, pkgAddress.missingPeers ?? {}), })) } diff --git a/packages/resolve-dependencies/src/resolveDependencyTree.ts b/packages/resolve-dependencies/src/resolveDependencyTree.ts index 7fe6ec6596..39e43feb92 100644 --- a/packages/resolve-dependencies/src/resolveDependencyTree.ts +++ b/packages/resolve-dependencies/src/resolveDependencyTree.ts @@ -208,8 +208,8 @@ export async function resolveDependencyTree ( } }), directNodeIdsByAlias: directNonLinkedDeps - .reduce((acc, dependency) => { - acc[dependency.alias] = dependency.nodeId + .reduce((acc, { alias, nodeId }) => { + acc[alias] = nodeId return acc }, {}), linkedDependencies, diff --git a/packages/resolve-dependencies/src/resolvePeers.ts b/packages/resolve-dependencies/src/resolvePeers.ts index 00d4652d13..fa7757f732 100644 --- a/packages/resolve-dependencies/src/resolvePeers.ts +++ b/packages/resolve-dependencies/src/resolvePeers.ts @@ -10,7 +10,9 @@ import { depPathToFilename, createPeersFolderSuffix } from 'dependency-path' import { KeyValuePair } from 'ramda' import fromPairs from 'ramda/src/fromPairs' import isEmpty from 'ramda/src/isEmpty' +import mapValues from 'ramda/src/map' import pick from 'ramda/src/pick' +import pickBy from 'ramda/src/pickBy' import scan from 'ramda/src/scan' import { DependenciesTree, @@ -24,7 +26,7 @@ export interface GenericDependenciesGraphNode { // at this point the version is really needed only for logging modules: string dir: string - children: { [alias: string]: string } + children: Record depth: number peerDependencies?: Dependencies transitivePeerDependencies: Set @@ -93,18 +95,12 @@ export function resolvePeers ( } Object.values(depGraph).forEach((node) => { - node.children = Object.keys(node.children).reduce((acc, alias) => { - acc[alias] = pathsByNodeId[node.children[alias]] ?? node.children[alias] - return acc - }, {}) + node.children = mapValues((childNodeId) => pathsByNodeId[childNodeId] ?? childNodeId, node.children) }) const dependenciesByProjectId: { [id: string]: { [alias: string]: string } } = {} for (const { directNodeIdsByAlias, id } of opts.projects) { - dependenciesByProjectId[id] = Object.keys(directNodeIdsByAlias).reduce((rootPathsByAlias, alias) => { - rootPathsByAlias[alias] = pathsByNodeId[directNodeIdsByAlias[alias]] - return rootPathsByAlias - }, {}) + dependenciesByProjectId[id] = mapValues((nodeId) => pathsByNodeId[nodeId], directNodeIdsByAlias) } return { dependenciesGraph: depGraph, @@ -376,12 +372,7 @@ function resolvePeersOfChildren ( missingPeers.forEach((missingPeer) => allMissingPeers.add(missingPeer)) } - const unknownResolvedPeersOfChildren = Object.keys(allResolvedPeers) - .filter((alias) => !children[alias]) - .reduce((acc, peer) => { - acc[peer] = allResolvedPeers[peer] - return acc - }, {}) + const unknownResolvedPeersOfChildren: Record = pickBy((_, alias) => !children[alias], allResolvedPeers) return { resolvedPeers: unknownResolvedPeersOfChildren, missingPeers: Array.from(allMissingPeers) } } diff --git a/packages/resolve-dependencies/src/toResolveImporter.ts b/packages/resolve-dependencies/src/toResolveImporter.ts index 5022a8796a..2bfe8f101e 100644 --- a/packages/resolve-dependencies/src/toResolveImporter.ts +++ b/packages/resolve-dependencies/src/toResolveImporter.ts @@ -117,10 +117,10 @@ function getPreferredVersionsFromPackage ( } function getVersionSpecsByRealNames (deps: Dependencies) { - return Object.keys(deps) - .reduce((acc, depName) => { - if (deps[depName].startsWith('npm:')) { - const pref = deps[depName].slice(4) + return Object.entries(deps) + .reduce((acc, [depName, currentPref]) => { + if (currentPref.startsWith('npm:')) { + const pref = currentPref.slice(4) const index = pref.lastIndexOf('@') const spec = pref.slice(index + 1) const selector = getVerSelType(spec) @@ -129,8 +129,8 @@ function getVersionSpecsByRealNames (deps: Dependencies) { acc[pkgName] = acc[pkgName] || {} acc[pkgName][selector.normalized] = selector.type } - } else if (!deps[depName].includes(':')) { // we really care only about semver specs - const selector = getVerSelType(deps[depName]) + } else if (!currentPref.includes(':')) { // we really care only about semver specs + const selector = getVerSelType(currentPref) if (selector != null) { acc[depName] = acc[depName] || {} acc[depName][selector.normalized] = selector.type diff --git a/packages/resolve-dependencies/src/updateLockfile.ts b/packages/resolve-dependencies/src/updateLockfile.ts index 4c1d3b6c3d..f163b7fca1 100644 --- a/packages/resolve-dependencies/src/updateLockfile.ts +++ b/packages/resolve-dependencies/src/updateLockfile.ts @@ -36,7 +36,7 @@ export function updateLockfile ( for (const [depPath, depNode] of Object.entries(dependenciesGraph)) { const [updatedOptionalDeps, updatedDeps] = partition( (child) => depNode.optionalDependencies.has(child.alias), - Object.keys(depNode.children).map((alias) => ({ alias, depPath: depNode.children[alias] })) + Object.entries(depNode.children).map(([alias, depPath]) => ({ alias, depPath })) ) lockfile.packages[depPath] = toLockfileDependency(pendingRequiresBuilds, depNode, { depGraph: dependenciesGraph, @@ -126,8 +126,8 @@ function toLockfileDependency ( } if (pkg.peerDependenciesMeta != null) { const normalizedPeerDependenciesMeta = {} - for (const peer of Object.keys(pkg.peerDependenciesMeta)) { - if (pkg.peerDependenciesMeta[peer].optional) { + for (const [peer, { optional }] of Object.entries(pkg.peerDependenciesMeta)) { + if (optional) { normalizedPeerDependenciesMeta[peer] = { optional: true } } } @@ -136,10 +136,10 @@ function toLockfileDependency ( } } if (pkg.additionalInfo.engines != null) { - for (const engine of Object.keys(pkg.additionalInfo.engines)) { - if (pkg.additionalInfo.engines[engine] === '*') continue + for (const [engine, version] of Object.entries(pkg.additionalInfo.engines)) { + if (version === '*') continue result['engines'] = result['engines'] || {} - result['engines'][engine] = pkg.additionalInfo.engines[engine] + result['engines'][engine] = version } } if (pkg.additionalInfo.cpu != null) { diff --git a/packages/tarball-fetcher/package.json b/packages/tarball-fetcher/package.json index 8fdb5e4047..be811a5a7f 100644 --- a/packages/tarball-fetcher/package.json +++ b/packages/tarball-fetcher/package.json @@ -41,6 +41,7 @@ "@pnpm/graceful-fs": "workspace:*", "@pnpm/prepare-package": "workspace:*", "@zkochan/retry": "^0.2.0", + "p-map-values": "^1.0.0", "ramda": "npm:@pnpm/ramda@0.28.1", "ssri": "^9.0.1" }, diff --git a/packages/tarball-fetcher/src/gitHostedTarballFetcher.ts b/packages/tarball-fetcher/src/gitHostedTarballFetcher.ts index b49a376d77..d370b9bed0 100644 --- a/packages/tarball-fetcher/src/gitHostedTarballFetcher.ts +++ b/packages/tarball-fetcher/src/gitHostedTarballFetcher.ts @@ -1,7 +1,7 @@ import { FetchFunction, FetchOptions } from '@pnpm/fetcher-base' import type { Cafs, FilesIndex, PackageFileInfo } from '@pnpm/cafs-types' import { preparePackage } from '@pnpm/prepare-package' -import fromPairs from 'ramda/src/fromPairs' +import pMapValues from 'p-map-values' import omit from 'ramda/src/omit' interface Resolution { @@ -38,19 +38,12 @@ async function prepareGitHostedPkg (filesIndex: FilesIndex, cafs: Cafs) { } export async function waitForFilesIndex (filesIndex: FilesIndex): Promise> { - return fromPairs( - await Promise.all( - Object.entries(filesIndex).map(async ([fileName, fileInfo]): Promise<[string, PackageFileInfo]> => { - const { integrity, checkedAt } = await fileInfo.writeResult - return [ - fileName, - { - ...omit(['writeResult'], fileInfo), - checkedAt, - integrity: integrity.toString(), - }, - ] - }) - ) - ) + return pMapValues(async (fileInfo) => { + const { integrity, checkedAt } = await fileInfo.writeResult + return { + ...omit(['writeResult'], fileInfo), + checkedAt, + integrity: integrity.toString(), + } + }, filesIndex) } diff --git a/packages/types/src/package.ts b/packages/types/src/package.ts index cc7adf21fe..1a1254fd0f 100644 --- a/packages/types/src/package.ts +++ b/packages/types/src/package.ts @@ -1,6 +1,4 @@ -export interface Dependencies { - [name: string]: string -} +export type Dependencies = Record export type PackageBin = string | { [commandName: string]: string } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5148aae27..7cdbed06e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -203,6 +203,9 @@ importers: '@pnpm/types': specifier: workspace:* version: link:../types + ramda: + specifier: npm:@pnpm/ramda@0.28.1 + version: /@pnpm/ramda/0.28.1 devDependencies: '@pnpm/audit': specifier: workspace:* @@ -213,6 +216,9 @@ importers: '@pnpm/lockfile-file': specifier: workspace:* version: link:../lockfile-file + '@types/ramda': + specifier: 0.28.15 + version: 0.28.15 nock: specifier: 13.2.9 version: 13.2.9 @@ -443,6 +449,9 @@ importers: '@pnpm/tarball-fetcher': specifier: workspace:* version: link:../tarball-fetcher + ramda: + specifier: npm:@pnpm/ramda@0.28.1 + version: /@pnpm/ramda/0.28.1 devDependencies: '@pnpm/client': specifier: workspace:* @@ -450,6 +459,9 @@ importers: '@pnpm/fetcher-base': specifier: workspace:* version: link:../fetcher-base + '@types/ramda': + specifier: 0.28.15 + version: 0.28.15 packages/command: devDependencies: @@ -697,6 +709,9 @@ importers: p-limit: specifier: ^3.1.0 version: 3.1.0 + p-map-values: + specifier: ^1.0.0 + version: 1.0.0 path-exists: specifier: ^4.0.0 version: 4.0.0 @@ -1137,6 +1152,9 @@ importers: '@pnpm/types': specifier: workspace:* version: link:../types + p-map-values: + specifier: ^1.0.0 + version: 1.0.0 ramda: specifier: npm:@pnpm/ramda@0.28.1 version: /@pnpm/ramda/0.28.1 @@ -1854,6 +1872,9 @@ importers: path-absolute: specifier: ^1.0.1 version: 1.0.1 + ramda: + specifier: npm:@pnpm/ramda@0.28.1 + version: /@pnpm/ramda/0.28.1 devDependencies: '@pnpm/constants': specifier: workspace:* @@ -2430,6 +2451,9 @@ importers: is-windows: specifier: ^1.0.2 version: 1.0.2 + ramda: + specifier: npm:@pnpm/ramda@0.28.1 + version: /@pnpm/ramda/0.28.1 read-yaml-file: specifier: ^2.1.0 version: 2.1.0 @@ -2443,6 +2467,9 @@ importers: '@types/is-windows': specifier: ^1.0.0 version: 1.0.0 + '@types/ramda': + specifier: 0.28.15 + version: 0.28.15 tempy: specifier: ^1.0.1 version: 1.0.1 @@ -2595,10 +2622,16 @@ importers: normalize-registry-url: specifier: 2.0.0 version: 2.0.0 + ramda: + specifier: npm:@pnpm/ramda@0.28.1 + version: /@pnpm/ramda/0.28.1 devDependencies: '@pnpm/normalize-registries': specifier: workspace:* version: 'link:' + '@types/ramda': + specifier: 0.28.15 + version: 0.28.15 packages/npm-resolver: dependencies: @@ -2864,6 +2897,9 @@ importers: p-limit: specifier: ^3.1.0 version: 3.1.0 + p-map-values: + specifier: ^1.0.0 + version: 1.0.0 p-queue: specifier: ^6.6.2 version: 6.6.2 @@ -5329,6 +5365,9 @@ importers: '@zkochan/retry': specifier: ^0.2.0 version: 0.2.0 + p-map-values: + specifier: ^1.0.0 + version: 1.0.0 ramda: specifier: npm:@pnpm/ramda@0.28.1 version: /@pnpm/ramda/0.28.1 @@ -6602,7 +6641,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 jest-message-util: 29.3.1 jest-util: 29.3.1 @@ -6623,14 +6662,14 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1_@babel+types@7.20.2 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.6.1 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.3.1_knywchxbgsftsng55fleunlmpi + jest-config: 29.3.1_wfpg435ycu2pg2wixt73olz6ti jest-haste-map: 29.3.1 jest-message-util: 29.3.1 jest-regex-util: 29.2.0 @@ -6658,7 +6697,7 @@ packages: dependencies: '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 jest-mock: 29.3.1 dev: true @@ -6685,7 +6724,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 14.18.33 + '@types/node': 18.11.9 jest-message-util: 29.3.1 jest-mock: 29.3.1 jest-util: 29.3.1 @@ -6718,7 +6757,7 @@ packages: '@jest/transform': 29.3.1_@babel+types@7.20.2 '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -6808,7 +6847,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -6820,7 +6859,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -12394,6 +12433,7 @@ packages: resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} dependencies: has: 1.0.3 + dev: true /is-date-object/1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -12671,7 +12711,7 @@ packages: '@jest/expect': 29.3.1 '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -12761,6 +12801,47 @@ packages: - supports-color dev: true + /jest-config/29.3.1_wfpg435ycu2pg2wixt73olz6ti: + resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.20.2 + '@jest/test-sequencer': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 + babel-jest: 29.3.1_ly7roekxem2nfwgjk4xqt7jx7e + chalk: 4.1.2 + ci-info: 3.6.1 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.3.1_@babel+types@7.20.2 + jest-environment-node: 29.3.1 + jest-get-type: 29.2.0 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-runner: 29.3.1_@babel+types@7.20.2 + jest-util: 29.3.1 + jest-validate: 29.3.1 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.3.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1_kluoused5zacjtflizwvdqgpom + transitivePeerDependencies: + - '@babel/types' + - supports-color + dev: true + /jest-diff/29.3.1: resolution: {integrity: sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -12796,7 +12877,7 @@ packages: '@jest/environment': 29.3.1 '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 jest-mock: 29.3.1 jest-util: 29.3.1 dev: true @@ -12812,7 +12893,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@types/graceful-fs': 4.1.5 - '@types/node': 14.18.33 + '@types/node': 18.11.9 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -12863,7 +12944,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 jest-util: 29.3.1 dev: true @@ -12918,7 +12999,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1_@babel+types@7.20.2 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -12950,7 +13031,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1_@babel+types@7.20.2 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -13007,7 +13088,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.1.2 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 ci-info: 3.5.0 graceful-fs: 4.2.10 @@ -13019,7 +13100,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 chalk: 4.1.2 ci-info: 3.6.1 graceful-fs: 4.2.10 @@ -13044,7 +13125,7 @@ packages: dependencies: '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 14.18.33 + '@types/node': 18.11.9 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -13056,7 +13137,7 @@ packages: resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 14.18.33 + '@types/node': 18.11.9 jest-util: 29.3.1 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14520,6 +14601,11 @@ packages: dependencies: p-limit: 3.1.0 + /p-map-values/1.0.0: + resolution: {integrity: sha512-/n8QJM4Os3HLRMSuQWwAocsMExENSQwWTgRi8m3JVEOWQ/4gud14igBcnYvSGQTbiyZbuizxEmwf0w3ITn67gg==} + engines: {node: '>=14'} + dev: false + /p-map/2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -15435,7 +15521,7 @@ packages: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} hasBin: true dependencies: - is-core-module: 2.9.0 + is-core-module: 2.11.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -17166,7 +17252,7 @@ packages: /wide-align/1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: - string-width: 1.0.2 + string-width: 4.2.3 /widest-line/3.1.0: resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} @@ -17602,6 +17688,7 @@ time: /p-every/2.0.0: '2019-03-15T09:22:34.849Z' /p-filter/2.1.0: '2019-04-04T04:54:11.010Z' /p-limit/3.1.0: '2020-11-25T07:42:37.364Z' + /p-map-values/1.0.0: '2022-11-19T01:54:52.912Z' /p-memoize/4.0.1: '2020-09-24T12:12:05.234Z' /p-queue/6.6.2: '2020-10-11T19:09:45.773Z' /p-settle/4.1.1: '2020-05-29T08:07:35.109Z' diff --git a/typings/local.d.ts b/typings/local.d.ts index e9244757b1..2ac66fa0a9 100644 --- a/typings/local.d.ts +++ b/typings/local.d.ts @@ -150,3 +150,8 @@ declare module 'string.prototype.replaceall' { const anything: any export = anything } + +declare module 'ramda/src/map' { + function map (fn: (x: V) => U, obj: Record): Record + export = map +}