feat: support libc field for package.json (#4605)

close #4454
This commit is contained in:
zoomdong
2022-05-10 23:21:30 +08:00
committed by GitHub
parent 325ed5cba8
commit 52b0576af4
23 changed files with 471 additions and 43 deletions

View File

@@ -0,0 +1,9 @@
---
"@pnpm/cli-utils": patch
"@pnpm/filter-lockfile": patch
"@pnpm/lockfile-file": patch
"@pnpm/package-is-installable": patch
"@pnpm/resolve-dependencies": patch
---
feat: support libc filed

View File

@@ -71,7 +71,7 @@
"hosted-git-info@4": "npm:@zkochan/hosted-git-info@^4.0.2",
"http-errors": "^1.7.3",
"istanbul-reports": "npm:@zkochan/istanbul-reports",
"js-yaml@^4.0.0": "npm:@zkochan/js-yaml@0.0.5",
"js-yaml@^4.0.0": "npm:@zkochan/js-yaml@0.0.6",
"lodash@<4.17.19": "^4.17.9",
"nopt@5": "npm:@pnpm/nopt@^0.2.1",
"pkg-fetch": "3.1.1",

View File

@@ -8,6 +8,7 @@ export function packageIsInstallable (
engines?: WantedEngine
cpu?: string[]
os?: string[]
libc?: string[]
},
opts: {
engineStrict?: boolean

View File

@@ -21,6 +21,7 @@ const PUBLISH_CONFIG_WHITELIST = new Set([
// These are useful to hide in order to avoid warnings during local development
'os',
'cpu',
'libc',
// https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html#version-selection-with-typesversions
'typesVersions',
])

View File

@@ -39,7 +39,8 @@
"@types/ramda": "0.27.39",
"tempy": "^1.0.0",
"write-yaml-file": "^4.2.0",
"yaml-tag": "1.1.0"
"yaml-tag": "1.1.0",
"detect-libc": "^2.0.1"
},
"dependencies": {
"@pnpm/constants": "workspace:6.1.0",

View File

@@ -137,6 +137,7 @@ function pkgAllDeps (
cpu: pkgSnapshot.cpu,
engines: pkgSnapshot.engines,
os: pkgSnapshot.os,
libc: pkgSnapshot.libc,
}
// TODO: depPath is not the package ID. Should be fixed
installable = opts.includeIncompatiblePackages || packageIsInstallable(pkgSnapshot.id ?? depPath, pkg, {

View File

@@ -1,6 +1,28 @@
import { LOCKFILE_VERSION } from '@pnpm/constants'
import { filterLockfileByImportersAndEngine } from '@pnpm/filter-lockfile'
const REGIONAL_ARCH = Object.assign({}, process.arch)
const REGIONAL_CPU = Object.assign({}, process.platform)
jest.mock('detect-libc', () => {
const orginal = jest.requireActual('detect-libc')
return {
...orginal,
familySync: () => 'musl',
}
})
afterEach(() => {
Object.defineProperties(process, {
platform: {
value: REGIONAL_CPU,
},
arch: {
value: REGIONAL_ARCH,
},
})
})
test('filterByImportersAndEngine(): skip packages that are not installable', () => {
const skippedPackages = new Set<string>(['/preserve-existing-skipped/1.0.0'])
const filteredLockfile = filterLockfileByImportersAndEngine(
@@ -171,3 +193,348 @@ test('filterByImportersAndEngine(): skip packages that are not installable', ()
})
expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0'])
})
test('filterByImportersAndEngine(): filter the packages that set os and cpu', () => {
Object.defineProperties(process, {
platform: {
value: 'darwin',
},
arch: {
value: 'x64',
},
})
const skippedPackages = new Set<string>(['/preserve-existing-skipped/1.0.0'])
const filteredLockfile = filterLockfileByImportersAndEngine(
{
importers: {
'project-1': {
dependencies: {
'prod-dep': '1.0.0',
},
devDependencies: {
'dev-dep': '1.0.0',
},
optionalDependencies: {
'not-skipped-optional': '1.0.0',
'optional-dep': '1.0.0',
},
specifiers: {
'dev-dep': '^1.0.0',
'not-skipped-optional': '^1.0.0',
'optional-dep': '^1.0.0',
'prod-dep': '^1.0.0',
},
},
'project-2': {
dependencies: {
'project-2-prod-dep': '1.0.0',
},
specifiers: {
'project-2-prod-dep': '^1.0.0',
},
},
},
lockfileVersion: LOCKFILE_VERSION,
packages: {
'/bar/1.0.0': {
resolution: { integrity: '' },
},
'/dev-dep/1.0.0': {
dev: true,
resolution: { integrity: '' },
},
'/foo/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/not-skipped-optional/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/optional-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
foo: '1.0.0',
},
os: ['linux'],
cpu: ['x64'],
optional: true,
resolution: { integrity: '' },
},
'/prod-dep-dep/1.0.0': {
resolution: { integrity: '' },
},
'/prod-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
'prod-dep-dep': '1.0.0',
},
optionalDependencies: {
'optional-dep': '1.0.0',
},
resolution: { integrity: '' },
},
'/project-2-prod-dep/1.0.0': {
resolution: { integrity: '' },
},
},
},
['project-1'],
{
currentEngine: {
nodeVersion: '10.0.0',
pnpmVersion: '2.0.0',
},
engineStrict: true,
failOnMissingDependencies: true,
include: {
dependencies: true,
devDependencies: true,
optionalDependencies: true,
},
lockfileDir: process.cwd(),
skipped: skippedPackages,
}
)
expect(filteredLockfile).toStrictEqual({
importers: {
'project-1': {
dependencies: {
'prod-dep': '1.0.0',
},
devDependencies: {
'dev-dep': '1.0.0',
},
optionalDependencies: {
'not-skipped-optional': '1.0.0',
'optional-dep': '1.0.0',
},
specifiers: {
'dev-dep': '^1.0.0',
'not-skipped-optional': '^1.0.0',
'optional-dep': '^1.0.0',
'prod-dep': '^1.0.0',
},
},
'project-2': {
dependencies: {
'project-2-prod-dep': '1.0.0',
},
specifiers: {
'project-2-prod-dep': '^1.0.0',
},
},
},
lockfileVersion: LOCKFILE_VERSION,
packages: {
'/bar/1.0.0': {
resolution: { integrity: '' },
},
'/dev-dep/1.0.0': {
dev: true,
resolution: { integrity: '' },
},
'/foo/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/not-skipped-optional/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/optional-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
foo: '1.0.0',
},
os: ['linux'],
cpu: ['x64'],
optional: true,
resolution: { integrity: '' },
},
'/prod-dep-dep/1.0.0': {
resolution: { integrity: '' },
},
'/prod-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
'prod-dep-dep': '1.0.0',
},
optionalDependencies: {
'optional-dep': '1.0.0',
},
resolution: { integrity: '' },
},
},
})
expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0'])
})
test('filterByImportersAndEngine(): filter the packages that set libc', () => {
const skippedPackages = new Set<string>(['/preserve-existing-skipped/1.0.0'])
const filteredLockfile = filterLockfileByImportersAndEngine(
{
importers: {
'project-1': {
dependencies: {
'prod-dep': '1.0.0',
},
devDependencies: {
'dev-dep': '1.0.0',
},
optionalDependencies: {
'not-skipped-optional': '1.0.0',
'optional-dep': '1.0.0',
},
specifiers: {
'dev-dep': '^1.0.0',
'not-skipped-optional': '^1.0.0',
'optional-dep': '^1.0.0',
'prod-dep': '^1.0.0',
},
},
'project-2': {
dependencies: {
'project-2-prod-dep': '1.0.0',
},
specifiers: {
'project-2-prod-dep': '^1.0.0',
},
},
},
lockfileVersion: LOCKFILE_VERSION,
packages: {
'/bar/1.0.0': {
resolution: { integrity: '' },
},
'/dev-dep/1.0.0': {
dev: true,
resolution: { integrity: '' },
},
'/foo/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/not-skipped-optional/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/optional-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
foo: '1.0.0',
},
libc: ['glibc'],
optional: true,
resolution: { integrity: '' },
},
'/prod-dep-dep/1.0.0': {
resolution: { integrity: '' },
},
'/prod-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
'prod-dep-dep': '1.0.0',
},
optionalDependencies: {
'optional-dep': '1.0.0',
},
resolution: { integrity: '' },
},
'/project-2-prod-dep/1.0.0': {
resolution: { integrity: '' },
},
},
},
['project-1'],
{
currentEngine: {
nodeVersion: '10.0.0',
pnpmVersion: '2.0.0',
},
engineStrict: true,
failOnMissingDependencies: true,
include: {
dependencies: true,
devDependencies: true,
optionalDependencies: true,
},
lockfileDir: process.cwd(),
skipped: skippedPackages,
}
)
expect(filteredLockfile).toStrictEqual({
importers: {
'project-1': {
dependencies: {
'prod-dep': '1.0.0',
},
devDependencies: {
'dev-dep': '1.0.0',
},
optionalDependencies: {
'not-skipped-optional': '1.0.0',
'optional-dep': '1.0.0',
},
specifiers: {
'dev-dep': '^1.0.0',
'not-skipped-optional': '^1.0.0',
'optional-dep': '^1.0.0',
'prod-dep': '^1.0.0',
},
},
'project-2': {
dependencies: {
'project-2-prod-dep': '1.0.0',
},
specifiers: {
'project-2-prod-dep': '^1.0.0',
},
},
},
lockfileVersion: LOCKFILE_VERSION,
packages: {
'/bar/1.0.0': {
resolution: { integrity: '' },
},
'/dev-dep/1.0.0': {
dev: true,
resolution: { integrity: '' },
},
'/foo/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/not-skipped-optional/1.0.0': {
optional: true,
resolution: { integrity: '' },
},
'/optional-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
foo: '1.0.0',
},
libc: ['glibc'],
optional: true,
resolution: { integrity: '' },
},
'/prod-dep-dep/1.0.0': {
resolution: { integrity: '' },
},
'/prod-dep/1.0.0': {
dependencies: {
bar: '1.0.0',
'prod-dep-dep': '1.0.0',
},
optionalDependencies: {
'optional-dep': '1.0.0',
},
resolution: { integrity: '' },
},
},
})
expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0'])
})

View File

@@ -1,3 +0,0 @@
/// <reference path="../../../typings/index.d.ts"/>
import './filterByImporters'
import './filterByImportersAndEngine'

View File

@@ -108,6 +108,7 @@ export default async function lockfileToDepGraph (
engines: pkgSnapshot.engines,
cpu: pkgSnapshot.cpu,
os: pkgSnapshot.os,
libc: pkgSnapshot.libc,
}
if (!opts.force &&
packageIsInstallable(packageId, pkg, {

View File

@@ -157,6 +157,7 @@ async function fetchDeps (
engines: pkgSnapshot.engines,
cpu: pkgSnapshot.cpu,
os: pkgSnapshot.os,
libc: pkgSnapshot.libc,
}
if (!opts.force &&
packageIsInstallable(packageId, pkg, {

View File

@@ -16,7 +16,8 @@
"_test": "jest",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
"compile": "tsc --build && pnpm run lint --fix",
"start": "tsc --watch"
},
"repository": "https://github.com/pnpm/pnpm/blob/main/packages/lockfile-file",
"keywords": [
@@ -53,7 +54,7 @@
"@pnpm/types": "workspace:8.0.1",
"@zkochan/rimraf": "^2.1.2",
"comver-to-semver": "^1.0.0",
"js-yaml": "npm:@zkochan/js-yaml@0.0.5",
"js-yaml": "npm:@zkochan/js-yaml@0.0.6",
"normalize-path": "^3.0.0",
"ramda": "^0.27.1",
"semver": "^7.3.4",

View File

@@ -11,22 +11,23 @@ const ORDERED_KEYS = {
engines: 5,
cpu: 6,
os: 7,
libc: 8,
deprecated: 8,
hasBin: 9,
prepare: 10,
requiresBuild: 11,
deprecated: 9,
hasBin: 10,
prepare: 11,
requiresBuild: 12,
bundleDependencies: 12,
peerDependencies: 13,
peerDependenciesMeta: 14,
bundleDependencies: 13,
peerDependencies: 14,
peerDependenciesMeta: 15,
dependencies: 15,
optionalDependencies: 16,
dependencies: 16,
optionalDependencies: 17,
transitivePeerDependencies: 17,
dev: 18,
optional: 19,
transitivePeerDependencies: 18,
dev: 19,
optional: 20,
}
const ROOT_KEYS_ORDER = {

View File

@@ -18,6 +18,7 @@ packages:
engines: {node: '>=10', npm: \\"\\\\nfoo\\\\n\\"}
cpu: [x86]
os: [darwin]
libc: [glibc]
dependencies:
is-positive: 2.0.0

View File

@@ -32,6 +32,7 @@ test('writeLockfiles()', async () => {
'is-positive': '2.0.0',
},
cpu: ['x86'],
libc: ['glibc'],
engines: {
node: '>=10',
npm: '\nfoo\n',

View File

@@ -90,6 +90,7 @@ export interface PackageSnapshot {
}
os?: string[]
cpu?: string[]
libc?: string[]
deprecated?: string
}

View File

@@ -32,6 +32,7 @@
"@pnpm/core-loggers": "workspace:7.0.1",
"@pnpm/error": "workspace:3.0.1",
"@pnpm/types": "workspace:8.0.1",
"detect-libc": "^2.0.1",
"execa": "npm:safe-execa@^0.1.1",
"mem": "^8.0.0",
"semver": "^7.3.4"

View File

@@ -1,4 +1,7 @@
import PnpmError from '@pnpm/error'
import { familySync as getLibcFamilySync } from 'detect-libc'
const currentLibc = getLibcFamilySync() ?? 'unknown'
export class UnsupportedPlatformError extends PnpmError {
public wanted: WantedPlatform
@@ -15,10 +18,8 @@ export default function checkPlatform (
packageId: string,
wantedPlatform: WantedPlatform
) {
const platform = process.platform
const arch = process.arch
let osOk = true
let cpuOk = true
const { platform, arch } = process
let osOk = true; let cpuOk = true; let libcOk = true
if (wantedPlatform.os) {
osOk = checkList(platform, wantedPlatform.os)
@@ -26,8 +27,12 @@ export default function checkPlatform (
if (wantedPlatform.cpu) {
cpuOk = checkList(arch, wantedPlatform.cpu)
}
if (!osOk || !cpuOk) {
return new UnsupportedPlatformError(packageId, wantedPlatform, { os: platform, cpu: arch })
if (wantedPlatform.libc && currentLibc !== 'unknown') {
libcOk = checkList(currentLibc, wantedPlatform.libc)
}
if (!osOk || !cpuOk || !libcOk) {
return new UnsupportedPlatformError(packageId, wantedPlatform, { os: platform, cpu: arch, libc: currentLibc })
}
return null
}
@@ -35,14 +40,13 @@ export default function checkPlatform (
export interface Platform {
cpu: string | string[]
os: string | string[]
libc: string | string[]
}
export type WantedPlatform = Partial<Platform>
function checkList (value: string, list: string | string[]) {
let tmp
let match = false
let blc = 0
let tmp; let match = false; let blc = 0
if (typeof list === 'string') {
list = [list]
}

View File

@@ -23,6 +23,7 @@ export default function packageIsInstallable (
engines?: WantedEngine
cpu?: string[]
os?: string[]
libc?: string[]
},
options: {
engineStrict?: boolean
@@ -67,6 +68,7 @@ export function checkPackage (
engines?: WantedEngine
cpu?: string[]
os?: string[]
libc?: string[]
},
options: {
nodeVersion?: string
@@ -76,6 +78,7 @@ export function checkPackage (
return checkPlatform(pkgId, {
cpu: manifest.cpu ?? ['any'],
os: manifest.os ?? ['any'],
libc: manifest.libc ?? ['any'],
}) ?? (
(manifest.engines == null)
? null

View File

@@ -2,10 +2,19 @@ import checkPlatform from '../lib/checkPlatform'
const packageId = 'registry.npmjs.org/foo/1.0.0'
jest.mock('detect-libc', () => {
const orginal = jest.requireActual('detect-libc')
return {
...orginal,
familySync: () => 'musl',
}
})
test('target cpu wrong', () => {
const target = {
cpu: 'enten-cpu',
os: 'any',
libc: 'any',
}
const err = checkPlatform(packageId, target)
expect(err).toBeTruthy()
@@ -16,6 +25,18 @@ test('os wrong', () => {
const target = {
cpu: 'any',
os: 'enten-os',
libc: 'any',
}
const err = checkPlatform(packageId, target)
expect(err).toBeTruthy()
expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM')
})
test('libc wrong', () => {
const target = {
cpu: 'any',
os: 'any',
libc: 'enten-libc',
}
const err = checkPlatform(packageId, target)
expect(err).toBeTruthy()
@@ -26,34 +47,35 @@ test('nothing wrong', () => {
const target = {
cpu: 'any',
os: 'any',
libc: 'any',
}
expect(checkPlatform(packageId, target)).toBeFalsy()
})
test('only target cpu wrong', () => {
const err = checkPlatform(packageId, { cpu: 'enten-cpu', os: 'any' })
const err = checkPlatform(packageId, { cpu: 'enten-cpu', os: 'any', libc: 'any' })
expect(err).toBeTruthy()
expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM')
})
test('only os wrong', () => {
const err = checkPlatform(packageId, { cpu: 'any', os: 'enten-os' })
const err = checkPlatform(packageId, { cpu: 'any', os: 'enten-os', libc: 'any' })
expect(err).toBeTruthy()
expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM')
})
test('everything wrong w/arrays', () => {
const err = checkPlatform(packageId, { cpu: ['enten-cpu'], os: ['enten-os'] })
const err = checkPlatform(packageId, { cpu: ['enten-cpu'], os: ['enten-os'], libc: ['enten-libc'] })
expect(err).toBeTruthy()
expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM')
})
test('os wrong (negation)', () => {
const err = checkPlatform(packageId, { cpu: 'any', os: `!${process.platform}` })
const err = checkPlatform(packageId, { cpu: 'any', os: `!${process.platform}`, libc: 'any' })
expect(err).toBeTruthy()
expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM')
})
test('nothing wrong (negation)', () => {
expect(checkPlatform(packageId, { cpu: '!enten-cpu', os: '!enten-os' })).toBe(null)
expect(checkPlatform(packageId, { cpu: '!enten-cpu', os: '!enten-os', libc: '!enten-libc' })).toBe(null)
})

View File

@@ -197,6 +197,7 @@ export interface ResolvedPackage {
}
cpu?: string[]
os?: string[]
libc?: string[]
}
}
@@ -878,6 +879,7 @@ function getResolvedPackage (
deprecated: options.pkg.deprecated,
engines: options.pkg.engines,
os: options.pkg.os,
libc: options.pkg.libc,
},
depPath: options.depPath,
dev: options.wantedDependency.dev,

View File

@@ -144,6 +144,9 @@ function toLockfileDependency (
if (pkg.additionalInfo.os != null) {
result['os'] = pkg.additionalInfo.os
}
if (pkg.additionalInfo.libc != null) {
result['libc'] = pkg.additionalInfo.libc
}
if (Array.isArray(pkg.additionalInfo.bundledDependencies) || Array.isArray(pkg.additionalInfo.bundleDependencies)) {
result['bundledDependencies'] = pkg.additionalInfo.bundledDependencies ?? pkg.additionalInfo.bundleDependencies
}

View File

@@ -93,6 +93,7 @@ export interface BaseManifest {
}
cpu?: string[]
os?: string[]
libc?: string[]
main?: string
module?: string
typings?: string

28
pnpm-lock.yaml generated
View File

@@ -12,7 +12,7 @@ overrides:
hosted-git-info@4: npm:@zkochan/hosted-git-info@^4.0.2
http-errors: ^1.7.3
istanbul-reports: npm:@zkochan/istanbul-reports
js-yaml@^4.0.0: npm:@zkochan/js-yaml@0.0.5
js-yaml@^4.0.0: npm:@zkochan/js-yaml@0.0.6
lodash@<4.17.19: ^4.17.9
nopt@5: npm:@pnpm/nopt@^0.2.1
pkg-fetch: 3.1.1
@@ -879,6 +879,7 @@ importers:
'@pnpm/types': workspace:8.0.1
'@types/ramda': 0.27.39
dependency-path: workspace:9.1.1
detect-libc: ^2.0.1
ramda: ^0.27.1
tempy: ^1.0.0
write-yaml-file: ^4.2.0
@@ -897,6 +898,7 @@ importers:
'@pnpm/filter-lockfile': 'link:'
'@pnpm/logger': 4.0.0
'@types/ramda': 0.27.39
detect-libc: 2.0.1
tempy: 1.0.1
write-yaml-file: 4.2.0
yaml-tag: 1.1.0
@@ -1383,7 +1385,7 @@ importers:
'@types/write-file-atomic': ^3.0.1
'@zkochan/rimraf': ^2.1.2
comver-to-semver: ^1.0.0
js-yaml: npm:@zkochan/js-yaml@0.0.5
js-yaml: npm:@zkochan/js-yaml@0.0.6
normalize-path: ^3.0.0
ramda: ^0.27.1
semver: ^7.3.4
@@ -1401,7 +1403,7 @@ importers:
'@pnpm/types': link:../types
'@zkochan/rimraf': 2.1.2
comver-to-semver: 1.0.0
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
normalize-path: 3.0.0
ramda: 0.27.2
semver: 7.3.7
@@ -1835,6 +1837,7 @@ importers:
'@pnpm/package-is-installable': workspace:6.0.2
'@pnpm/types': workspace:8.0.1
'@types/semver': ^7.3.4
detect-libc: ^2.0.1
execa: npm:safe-execa@^0.1.1
mem: ^8.0.0
semver: ^7.3.4
@@ -1842,6 +1845,7 @@ importers:
'@pnpm/core-loggers': link:../core-loggers
'@pnpm/error': link:../error
'@pnpm/types': link:../types
detect-libc: 2.0.1
execa: /safe-execa/0.1.1
mem: 8.1.1
semver: 7.3.7
@@ -4535,7 +4539,7 @@ packages:
globals: 13.13.0
ignore: 5.2.0
import-fresh: 3.3.0
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
@@ -6018,8 +6022,8 @@ packages:
istanbul-lib-report: 3.0.0
dev: true
/@zkochan/js-yaml/0.0.5:
resolution: {integrity: sha512-/uaB1kf+t+UATNUSyzHSzy4JqKOh2Y77gdCnhQEKTX/vrpQp8qjvohvC6eG9X4spQf0a8TKL0qF5LiFNj+GrJw==}
/@zkochan/js-yaml/0.0.6:
resolution: {integrity: sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==}
hasBin: true
dependencies:
argparse: 2.0.1
@@ -7753,6 +7757,10 @@ packages:
hasBin: true
dev: true
/detect-libc/2.0.1:
resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==}
engines: {node: '>=8'}
/detect-newline/3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
@@ -8470,7 +8478,7 @@ packages:
import-fresh: 3.3.0
imurmurhash: 0.1.4
is-glob: 4.0.3
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
@@ -12909,7 +12917,7 @@ packages:
resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==}
engines: {node: '>=10.13'}
dependencies:
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
strip-bom: 4.0.0
/readable-stream/2.3.7:
@@ -14851,7 +14859,7 @@ packages:
fast-safe-stringify: 2.1.1
handlebars: 4.7.7
http-errors: 1.8.1
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
JSONStream: 1.3.5
jsonwebtoken: 8.5.1
kleur: 4.1.4
@@ -15185,7 +15193,7 @@ packages:
resolution: {integrity: sha512-LwyucHy0uhWqbrOkh9cBluZBeNVxzHjDaE9mwepZG3n3ZlbM4v3ndrFw51zW/NXYFFqP+QWZ72ihtLWTh05e4Q==}
engines: {node: '>=10.13'}
dependencies:
js-yaml: /@zkochan/js-yaml/0.0.5
js-yaml: /@zkochan/js-yaml/0.0.6
write-file-atomic: 3.0.3
/ws/7.5.7: