update-browserslist-db 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +84 -11
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -17,7 +17,6 @@ function BrowserslistUpdateError(message) {
|
|
|
17
17
|
|
|
18
18
|
BrowserslistUpdateError.prototype = Error.prototype
|
|
19
19
|
|
|
20
|
-
// Check if HADOOP_HOME is set to determine if this is running in a Hadoop environment
|
|
21
20
|
const YARN_CMD = process.env.HADOOP_HOME ? 'yarnpkg' : 'yarn'
|
|
22
21
|
|
|
23
22
|
/* c8 ignore next 3 */
|
|
@@ -70,6 +69,14 @@ function getLatestInfo(lock) {
|
|
|
70
69
|
try {
|
|
71
70
|
if (lock.mode === 'yarn') {
|
|
72
71
|
if (lock.version === 1) {
|
|
72
|
+
let yarnMajorVersion = getYarnMajor()
|
|
73
|
+
if (yarnMajorVersion !== 1) {
|
|
74
|
+
throw new BrowserslistUpdateError(
|
|
75
|
+
'This project has a Yarn v1 (classic) lockfile, but the installed ' +
|
|
76
|
+
`Yarn is Berry v${yarnMajorVersion}. Install and activate Yarn classic ` +
|
|
77
|
+
'to update caniuse-lite.'
|
|
78
|
+
)
|
|
79
|
+
}
|
|
73
80
|
return JSON.parse(
|
|
74
81
|
execSync(YARN_CMD + ' info caniuse-lite --json').toString()
|
|
75
82
|
).data
|
|
@@ -96,7 +103,20 @@ function getLatestInfo(lock) {
|
|
|
96
103
|
|
|
97
104
|
return JSON.parse(execSync('npm show caniuse-lite --json').toString())
|
|
98
105
|
} catch (e) {
|
|
99
|
-
|
|
106
|
+
// ENOENT / status 127 are the POSIX "command not found" signals. cmd.exe
|
|
107
|
+
// instead reports `'<binary>' is not recognized as an internal or external
|
|
108
|
+
// command`. Anchor that phrase to the binary we actually launched so an
|
|
109
|
+
// unrelated "is not recognized" line in a real failure's output (e.g. a
|
|
110
|
+
// nested tool) is not mistaken for a missing package manager.
|
|
111
|
+
let binary = lock.mode === 'yarn' ? YARN_CMD : lock.mode
|
|
112
|
+
let missingOnWindows = new RegExp(
|
|
113
|
+
"'" + binary + "' is not recognized as an internal or external command"
|
|
114
|
+
)
|
|
115
|
+
if (
|
|
116
|
+
e.code === 'ENOENT' ||
|
|
117
|
+
e.status === 127 ||
|
|
118
|
+
missingOnWindows.test(commandErrorText(e))
|
|
119
|
+
) {
|
|
100
120
|
throw new BrowserslistUpdateError(
|
|
101
121
|
'Cannot find ' +
|
|
102
122
|
lock.mode +
|
|
@@ -109,6 +129,11 @@ function getLatestInfo(lock) {
|
|
|
109
129
|
}
|
|
110
130
|
}
|
|
111
131
|
|
|
132
|
+
function getYarnMajor() {
|
|
133
|
+
let version = execSync(YARN_CMD + ' --version').toString().trim()
|
|
134
|
+
return Number(version.split('.')[0])
|
|
135
|
+
}
|
|
136
|
+
|
|
112
137
|
function getBrowsers() {
|
|
113
138
|
let browserslist = require('browserslist')
|
|
114
139
|
return browserslist().reduce((result, entry) => {
|
|
@@ -171,7 +196,13 @@ function deletePackage(node, metadata) {
|
|
|
171
196
|
let yarnVersionRe = /version "(.*?)"/
|
|
172
197
|
|
|
173
198
|
function updateYarnLockfile(lock, latest) {
|
|
174
|
-
|
|
199
|
+
// Split entries on blank lines using LF. A CRLF lockfile has `\r\n\r\n`
|
|
200
|
+
// between entries, which `\n{2,}` cannot match, so the whole file would
|
|
201
|
+
// collapse into one block and no version be detected. CRLF can occur on any
|
|
202
|
+
// OS (git autocrlf, editor settings), so normalize regardless of platform;
|
|
203
|
+
// updateLockfile restores the original EOL on the returned content.
|
|
204
|
+
let normalized = lock.content.replace(/\r\n/g, '\n')
|
|
205
|
+
let blocks = normalized.split(/(\n{2,})/).map(block => {
|
|
175
206
|
return block.split('\n')
|
|
176
207
|
})
|
|
177
208
|
let versions = {}
|
|
@@ -335,8 +366,36 @@ function commandErrorText(error) {
|
|
|
335
366
|
.join('\n')
|
|
336
367
|
}
|
|
337
368
|
|
|
369
|
+
function quotePnpmArg(arg) {
|
|
370
|
+
// cmd.exe expands %VAR% and !VAR! even inside double quotes. It also ignores
|
|
371
|
+
// the backslash in `\"`, so JSON values end up outside its quotes, where
|
|
372
|
+
// ^ & | < > ( ) run commands or redirect output. Refuse rather than run
|
|
373
|
+
// a mangled command.
|
|
374
|
+
if (/[%!^&|<>()]/.test(arg)) {
|
|
375
|
+
throw new BrowserslistUpdateError(
|
|
376
|
+
'Cannot safely pass any of %!^&|<>() to pnpm on Windows: ' + arg
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
if (!/[\s"]/.test(arg)) return arg
|
|
380
|
+
// Escape embedded quotes (doubling any backslash run that precedes them) and
|
|
381
|
+
// double a trailing backslash run so it cannot escape the closing quote.
|
|
382
|
+
return '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, '$1$1') + '"'
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function runPnpm(args, options = {}) {
|
|
386
|
+
// Node on Windows cannot launch pnpm's `.cmd` shim without a shell
|
|
387
|
+
if (process.platform === 'win32') {
|
|
388
|
+
return execFileSync('pnpm', args.map(quotePnpmArg), {
|
|
389
|
+
...options,
|
|
390
|
+
shell: true
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return execFileSync('pnpm', args, options)
|
|
395
|
+
}
|
|
396
|
+
|
|
338
397
|
function getPnpmConfig(name) {
|
|
339
|
-
let output =
|
|
398
|
+
let output = runPnpm([
|
|
340
399
|
'config',
|
|
341
400
|
'get',
|
|
342
401
|
name,
|
|
@@ -349,7 +408,7 @@ function getPnpmPackageTimes(name) {
|
|
|
349
408
|
let times
|
|
350
409
|
try {
|
|
351
410
|
times = JSON.parse(
|
|
352
|
-
|
|
411
|
+
runPnpm(['info', name, 'time', '--json']).toString()
|
|
353
412
|
)
|
|
354
413
|
} catch (error) /* c8 ignore start */ {
|
|
355
414
|
throw new BrowserslistUpdateError(
|
|
@@ -438,6 +497,10 @@ function updatePnpmStrict(print, lock, packages) {
|
|
|
438
497
|
? readFileSync(workspaceFile)
|
|
439
498
|
: undefined
|
|
440
499
|
let originalLockfile = readFileSync(lock.file)
|
|
500
|
+
let packageFile = join(packageDir, 'package.json')
|
|
501
|
+
let originalPackage = existsSync(packageFile)
|
|
502
|
+
? readFileSync(packageFile)
|
|
503
|
+
: undefined
|
|
441
504
|
let command = 'pnpm config set overrides'
|
|
442
505
|
|
|
443
506
|
print(
|
|
@@ -452,8 +515,7 @@ function updatePnpmStrict(print, lock, packages) {
|
|
|
452
515
|
)
|
|
453
516
|
|
|
454
517
|
try {
|
|
455
|
-
|
|
456
|
-
'pnpm',
|
|
518
|
+
runPnpm(
|
|
457
519
|
[
|
|
458
520
|
'config',
|
|
459
521
|
'set',
|
|
@@ -472,7 +534,7 @@ function updatePnpmStrict(print, lock, packages) {
|
|
|
472
534
|
pico.yellow('$ ' + command) +
|
|
473
535
|
' (with temporary policy-compliant overrides)\n'
|
|
474
536
|
)
|
|
475
|
-
|
|
537
|
+
runPnpm(['install', '--lockfile-only'], { cwd: packageDir })
|
|
476
538
|
|
|
477
539
|
restoreFile(workspaceFile, originalWorkspace)
|
|
478
540
|
// The lockfile no longer matches the restored overrides, and pnpm
|
|
@@ -481,11 +543,12 @@ function updatePnpmStrict(print, lock, packages) {
|
|
|
481
543
|
print(
|
|
482
544
|
'Removing temporary pnpm overrides\n' + pico.yellow('$ ' + command) + '\n'
|
|
483
545
|
)
|
|
484
|
-
|
|
546
|
+
runPnpm(['install', '--no-frozen-lockfile'], {
|
|
485
547
|
cwd: packageDir
|
|
486
548
|
})
|
|
487
549
|
} catch (error) /* c8 ignore start */ {
|
|
488
550
|
restoreFile(workspaceFile, originalWorkspace)
|
|
551
|
+
restoreFile(packageFile, originalPackage)
|
|
489
552
|
writeFileSync(lock.file, originalLockfile)
|
|
490
553
|
print(pico.red(commandErrorText(error)))
|
|
491
554
|
print(
|
|
@@ -504,12 +567,22 @@ function updatePnpm(print, lock) {
|
|
|
504
567
|
|
|
505
568
|
print('Updating caniuse-lite version\n' + pico.yellow('$ ' + command) + '\n')
|
|
506
569
|
try {
|
|
507
|
-
|
|
570
|
+
runPnpm(['up', '--depth=9999', '--no-save', ...packages], {
|
|
508
571
|
stdio: 'pipe'
|
|
509
572
|
})
|
|
510
573
|
} catch (error) /* c8 ignore start */ {
|
|
511
574
|
let text = commandErrorText(error)
|
|
512
|
-
|
|
575
|
+
// pnpm versions before 12.4.2 can fail `up --no-save` under strict
|
|
576
|
+
// minimumReleaseAge. The error differs by version: 10 uses
|
|
577
|
+
// NO_MATURE_MATCHING_VERSION, 11 uses MINIMUM_RELEASE_AGE_VIOLATION, and
|
|
578
|
+
// 12.0–12.4.1 uses STRICT_MIN_RELEASE_AGE_REQUIRES_SAVE. In each case,
|
|
579
|
+
// resolve and pin the newest mature versions ourselves. pnpm 12.4.2+ does
|
|
580
|
+
// this natively and succeeds before reaching this catch.
|
|
581
|
+
if (
|
|
582
|
+
text.includes('ERR_PNPM_STRICT_MIN_RELEASE_AGE_REQUIRES_SAVE') ||
|
|
583
|
+
text.includes('ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION') ||
|
|
584
|
+
text.includes('ERR_PNPM_NO_MATURE_MATCHING_VERSION')
|
|
585
|
+
) {
|
|
513
586
|
updatePnpmStrict(print, lock, packages)
|
|
514
587
|
} else {
|
|
515
588
|
print(pico.red(text))
|