Files
pnpm/packages/dependency-path/src/index.ts
Brandon Cheng e9aa6f682a chore(deps): update TypeScript 5.1.6 -> 5.2.2 (#7016)
* test: use sha512 integrity in fixtures to fix ci break

* test: update snapshots for sha512 fixture change

* chore(deps): remove unneeded peer dependency exception

The `peerDependencyRules.allowedVersions` exception on
`@typescript-eslint/eslint-plugin` no longer seems to be necessary.
Removing it does not introduce any new peer dependency errors on
`pnpm install`.

I suspect this was needed for the
`eslint-config-standard-with-typescript` dependency in the past, but a
@typescript-eslint/eslint-plugin upgrade made it no longer necessary.

* chore(deps): update @typescript-eslint dependencies 5.62.0 -> 6.5.0

@typescript-eslint 6.5.0 is the first version to introduce support for
TypeScript 5.2.

https://github.com/typescript-eslint/typescript-eslint/releases/tag/v6.5.0

```
=============

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=3.3.1 <5.2.0

YOUR TYPESCRIPT VERSION: 5.2.2

Please only submit bug reports when using the officially supported version.
```

* chore(deps): update eslint-config-standard-with-typescript 37.0.0 -> 39.0.0

Version 38.0.0 is the first version to support @typescript-eslint v6.
https://github.com/standard/eslint-config-standard-with-typescript/releases/tag/v38.0.0

Otherwise the following error appears.

```
> eslint "src/**/*.ts" "test/**/*.ts" "--fix"

Oops! Something went wrong! :(

ESLint: 8.47.0

Error: ../../.eslintrc.json » @pnpm/eslint-config » eslint-config-standard-with-typescript:
        Configuration for rule "@typescript-eslint/restrict-plus-operands" is invalid:
        Value {"checkCompoundAssignments":true} should NOT have additional properties.

    at ConfigValidator.validateRuleOptions (/Users/gluxon/Developer/pnpm/node_modules/.pnpm/@eslint+eslintrc@2.1.2/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2039:23)
    at /Users/gluxon/Developer/pnpm/node_modules/.pnpm/@eslint+eslintrc@2.1.2/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2094:18
```

* chore: remove unnecessary disables for restrict-template-expressions

The `@typescript-eslint/restrict-template-expressions` rule relaxed
what types are allowed in template expressions.

c13ce0b4f7 (diff-b852e1e199d2976eee1183fc84ac12a5d42fc61f0ae4b1c290dd54d621546db0)

Many of these disables were for interpolated values that had an `any`
type.

* chore: remove unnecessary disables for restrict-plus-operands

The original error was:

```
Invalid operand for a '+' operation. Operands must each be a number or string. Got `any`. eslint@typescript-eslint/restrict-plus-operands
```

It look like the newer version now allows `any`.

* style: fix errors of prefer-optional-chain and prefer-nullish-coalescing

The `@typescript-eslint/prefer-optional-chain` and
`@typescript-eslint/prefer-nullish-coalescing` rules got a bit
smarter. This commit applies autofixes. I believe the changes should be
equivalent to what existed before.

Example of the new `@typescript-eslint/prefer-optional-chain` lints.

```
pnpm/pkg-manifest/exportable-manifest/src/index.ts
  71:10  error  Prefer using an optional chain expression instead, as it's more concise and easier to read  @typescript-eslint/prefer-optional-chain
  87:10  error  Prefer using an optional chain expression instead, as it's more concise and easier to read  @typescript-eslint/prefer-optional-chain
```

Example of the new `@typescript-eslint/prefer-nullish-coalescing` lints.

```
pnpm/fs/find-packages/src/index.ts
  32:38  error  Prefer using nullish coalescing operator (`??`) instead of a ternary expression, as it is simpler to read  @typescript-eslint/prefer-nullish-coalescing
```

* chore(deps): update TypeScript 5.1.6 -> 5.2.2

* chore(deps): update @yarnpkg/core->@types/lodash override to 4.14.197

This fixes a compilation error that appears on TypeScript 5.2.2. This
error was fixed in a later version of `@types/lodash`.

https://github.com/DefinitelyTyped/DefinitelyTyped/pull/66123

```
../node_modules/.pnpm/@types+lodash@4.14.181/node_modules/@types/lodash/index.d.ts:45:15 - error TS2428: All declarations of 'WeakMap' must have identical type parameters.

45     interface WeakMap<K extends object, V> { }
                 ~~~~~~~

Found 4 errors.
```
2023-08-31 16:27:01 +03:00

195 lines
6.0 KiB
TypeScript

import { createBase32Hash } from '@pnpm/crypto.base32-hash'
import { type Registries } from '@pnpm/types'
import encodeRegistry from 'encode-registry'
import semver from 'semver'
export function isAbsolute (dependencyPath: string) {
return dependencyPath[0] !== '/'
}
export function resolve (
registries: Registries,
resolutionLocation: string
) {
if (!isAbsolute(resolutionLocation)) {
let registryUrl!: string
if (resolutionLocation[1] === '@') {
const slashIndex = resolutionLocation.indexOf('/', 1)
const scope = resolutionLocation.slice(1, slashIndex !== -1 ? slashIndex : 0)
registryUrl = registries[scope] || registries.default
} else {
registryUrl = registries.default
}
const registryDirectory = encodeRegistry(registryUrl)
return `${registryDirectory}${resolutionLocation}`
}
return resolutionLocation
}
export function indexOfPeersSuffix (depPath: string) {
if (!depPath.endsWith(')')) return -1
let open = true
for (let i = depPath.length - 2; i >= 0; i--) {
if (depPath[i] === '(') {
open = false
} else if (depPath[i] === ')') {
if (open) return -1
open = true
} else if (!open) {
return i + 1
}
}
return -1
}
export function tryGetPackageId (registries: Registries, relDepPath: string) {
if (relDepPath[0] !== '/') {
return null
}
const sepIndex = indexOfPeersSuffix(relDepPath)
if (sepIndex !== -1) {
return resolve(registries, relDepPath.substring(0, sepIndex))
}
const underscoreIndex = relDepPath.indexOf('_', relDepPath.lastIndexOf('/'))
if (underscoreIndex !== -1) {
return resolve(registries, relDepPath.slice(0, underscoreIndex))
}
return resolve(registries, relDepPath)
}
export function refToAbsolute (
reference: string,
pkgName: string,
registries: Registries
) {
if (reference.startsWith('link:')) {
return null
}
if (!reference.includes('/') || reference.includes('(') && reference.lastIndexOf('/', reference.indexOf('(')) === -1) {
const registryName = encodeRegistry(getRegistryByPackageName(registries, pkgName))
return `${registryName}/${pkgName}/${reference}`
}
if (reference[0] !== '/') return reference
const registryName = encodeRegistry(getRegistryByPackageName(registries, pkgName))
return `${registryName}${reference}`
}
export function getRegistryByPackageName (registries: Registries, packageName: string) {
if (packageName[0] !== '@') return registries.default
const scope = packageName.substring(0, packageName.indexOf('/'))
return registries[scope] || registries.default
}
export function relative (
registries: Registries,
packageName: string,
absoluteResolutionLoc: string
) {
const registryName = encodeRegistry(getRegistryByPackageName(registries, packageName))
if (absoluteResolutionLoc.startsWith(`${registryName}/`)) {
return absoluteResolutionLoc.slice(absoluteResolutionLoc.indexOf('/'))
}
return absoluteResolutionLoc
}
export function refToRelative (
reference: string,
pkgName: string
): string | null {
if (reference.startsWith('link:')) {
return null
}
if (reference.startsWith('file:')) {
return reference
}
if (!reference.includes('/') || reference.includes('(') && reference.lastIndexOf('/', reference.indexOf('(')) === -1) {
return `/${pkgName}/${reference}`
}
return reference
}
export function parse (dependencyPath: string) {
// eslint-disable-next-line: strict-type-predicates
if (typeof dependencyPath !== 'string') {
throw new TypeError(`Expected \`dependencyPath\` to be of type \`string\`, got \`${
// eslint-disable-next-line: strict-type-predicates
dependencyPath === null ? 'null' : typeof dependencyPath
}\``)
}
const _isAbsolute = isAbsolute(dependencyPath)
const parts = dependencyPath.split('/')
if (!_isAbsolute) parts.shift()
const host = _isAbsolute ? parts.shift() : undefined
if (parts.length === 0) return {
host,
isAbsolute: _isAbsolute,
}
const name = parts[0].startsWith('@')
? `${parts.shift()}/${parts.shift()}`
: parts.shift()
let version = parts.join('/')
if (version) {
let peerSepIndex!: number
let peersSuffix: string | undefined
if (version.includes('(') && version.endsWith(')')) {
peerSepIndex = version.indexOf('(')
if (peerSepIndex !== -1) {
peersSuffix = version.substring(peerSepIndex)
version = version.substring(0, peerSepIndex)
}
} else {
peerSepIndex = version.indexOf('_')
if (peerSepIndex !== -1) {
peersSuffix = version.substring(peerSepIndex + 1)
version = version.substring(0, peerSepIndex)
}
}
if (semver.valid(version)) {
return {
host,
isAbsolute: _isAbsolute,
name,
peersSuffix,
version,
}
}
}
if (!_isAbsolute) throw new Error(`${dependencyPath} is an invalid relative dependency path`)
return {
host,
isAbsolute: _isAbsolute,
}
}
const MAX_LENGTH_WITHOUT_HASH = 120 - 26 - 1
export function depPathToFilename (depPath: string) {
let filename = depPathToFilenameUnescaped(depPath).replace(/[\\/:*?"<>|]/g, '+')
if (filename.includes('(')) {
filename = filename
.replace(/(\)\()|\(/g, '_')
.replace(/\)$/, '')
}
if (filename.length > 120 || filename !== filename.toLowerCase() && !filename.startsWith('file+')) {
return `${filename.substring(0, MAX_LENGTH_WITHOUT_HASH)}_${createBase32Hash(filename)}`
}
return filename
}
function depPathToFilenameUnescaped (depPath: string) {
if (depPath.indexOf('file:') !== 0) {
if (depPath.startsWith('/')) {
depPath = depPath.substring(1)
}
const index = depPath.lastIndexOf('/', depPath.includes('(') ? depPath.indexOf('(') - 1 : depPath.length)
return `${depPath.substring(0, index)}@${depPath.slice(index + 1)}`
}
return depPath.replace(':', '+')
}
export function createPeersFolderSuffix (peers: Array<{ name: string, version: string }>): string {
const folderName = peers.map(({ name, version }) => `${name}@${version}`).sort().join(')(')
return `(${folderName})`
}