update-browserslist-db 1.3.1 → 1.3.3
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/check-npm-version.js +2 -1
- package/cli.js +1 -1
- package/index.js +238 -32
- package/package.json +1 -1
package/check-npm-version.js
CHANGED
|
@@ -4,7 +4,8 @@ let pico = require('picocolors')
|
|
|
4
4
|
|
|
5
5
|
if (!existsSync('deno.lock')) {
|
|
6
6
|
try {
|
|
7
|
-
let
|
|
7
|
+
let output = execSync('npm -v').toString().trim()
|
|
8
|
+
let version = parseInt(output.replace(/^[^\d]*/, ''))
|
|
8
9
|
if (version <= 6) {
|
|
9
10
|
process.stderr.write(
|
|
10
11
|
pico.red(
|
package/cli.js
CHANGED
|
@@ -28,7 +28,7 @@ function error(msg) {
|
|
|
28
28
|
if (isArg('--help') || isArg('-h')) {
|
|
29
29
|
process.stdout.write(getPackage().description + '.\n\n' + USAGE + '\n')
|
|
30
30
|
} else if (isArg('--version') || isArg('-v')) {
|
|
31
|
-
process.stdout.write('
|
|
31
|
+
process.stdout.write(getPackage().name + ' ' + getPackage().version + '\n')
|
|
32
32
|
} else {
|
|
33
33
|
try {
|
|
34
34
|
updateDb()
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
let { execSync } = require('child_process')
|
|
1
|
+
let { execFileSync, execSync } = require('child_process')
|
|
2
2
|
let escalade = require('escalade/sync')
|
|
3
|
-
let { existsSync, readFileSync, writeFileSync } = require('fs')
|
|
3
|
+
let { existsSync, readFileSync, unlinkSync, writeFileSync } = require('fs')
|
|
4
4
|
let { dirname, join } = require('path')
|
|
5
5
|
let pico = require('picocolors')
|
|
6
6
|
|
|
@@ -67,31 +67,46 @@ function detectLockfile() {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
function getLatestInfo(lock) {
|
|
70
|
-
|
|
71
|
-
if (lock.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
try {
|
|
71
|
+
if (lock.mode === 'yarn') {
|
|
72
|
+
if (lock.version === 1) {
|
|
73
|
+
return JSON.parse(
|
|
74
|
+
execSync(YARN_CMD + ' info caniuse-lite --json').toString()
|
|
75
|
+
).data
|
|
76
|
+
} else {
|
|
77
|
+
return JSON.parse(
|
|
78
|
+
execSync(YARN_CMD + ' npm info caniuse-lite --json').toString()
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (lock.mode === 'pnpm') {
|
|
83
|
+
return JSON.parse(execSync('pnpm info caniuse-lite --json').toString())
|
|
84
|
+
}
|
|
85
|
+
if (lock.mode === 'bun') {
|
|
86
|
+
return JSON.parse(execSync('bun info caniuse-lite --json').toString())
|
|
87
|
+
}
|
|
88
|
+
if (lock.mode === 'deno') {
|
|
89
|
+
let result = JSON.parse(
|
|
90
|
+
execSync(
|
|
91
|
+
'deno run -A npm:npm show caniuse-lite version --json'
|
|
92
|
+
).toString()
|
|
78
93
|
)
|
|
94
|
+
return { version: Array.isArray(result) ? result[0] : result }
|
|
79
95
|
}
|
|
80
|
-
}
|
|
81
|
-
if (lock.mode === 'pnpm') {
|
|
82
|
-
return JSON.parse(execSync('pnpm info caniuse-lite --json').toString())
|
|
83
|
-
}
|
|
84
|
-
if (lock.mode === 'bun') {
|
|
85
|
-
return JSON.parse(execSync(' bun info caniuse-lite --json').toString())
|
|
86
|
-
}
|
|
87
|
-
if (lock.mode === 'deno') {
|
|
88
|
-
let result = JSON.parse(
|
|
89
|
-
execSync('deno x -y npm:npm show caniuse-lite version --json').toString()
|
|
90
|
-
)
|
|
91
|
-
return { version: Array.isArray(result) ? result[0] : result }
|
|
92
|
-
}
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
return JSON.parse(execSync('npm show caniuse-lite --json').toString())
|
|
98
|
+
} catch (e) {
|
|
99
|
+
if (e.code === 'ENOENT' || e.status === 127) {
|
|
100
|
+
throw new BrowserslistUpdateError(
|
|
101
|
+
'Cannot find ' +
|
|
102
|
+
lock.mode +
|
|
103
|
+
' binary in PATH. Please install ' +
|
|
104
|
+
lock.mode +
|
|
105
|
+
' or run updates manually.'
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
throw e
|
|
109
|
+
}
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
function getBrowsers() {
|
|
@@ -209,7 +224,7 @@ function updatePackageManually(print, lock, latest) {
|
|
|
209
224
|
let caniuseVersions = Object.keys(lockfileData.versions).sort()
|
|
210
225
|
if (caniuseVersions.length === 1 && caniuseVersions[0] === latest.version) {
|
|
211
226
|
print(
|
|
212
|
-
'Installed version:
|
|
227
|
+
'Installed version: ' +
|
|
213
228
|
pico.bold(pico.green(caniuseVersions[0])) +
|
|
214
229
|
'\n' +
|
|
215
230
|
pico.bold(pico.green('caniuse-lite is up to date')) +
|
|
@@ -223,7 +238,7 @@ function updatePackageManually(print, lock, latest) {
|
|
|
223
238
|
}
|
|
224
239
|
print(
|
|
225
240
|
'Installed version' +
|
|
226
|
-
(caniuseVersions.length === 1 ? ':
|
|
241
|
+
(caniuseVersions.length === 1 ? ': ' : 's: ') +
|
|
227
242
|
pico.bold(pico.red(caniuseVersions.join(', '))) +
|
|
228
243
|
'\n' +
|
|
229
244
|
'Removing old caniuse-lite from lock file\n'
|
|
@@ -313,6 +328,199 @@ function updateBun(print, lock, latest) {
|
|
|
313
328
|
updateWith(print, 'bun install', 'Removing the temporary override')
|
|
314
329
|
}
|
|
315
330
|
|
|
331
|
+
function commandErrorText(error) {
|
|
332
|
+
return [error.message, error.stdout, error.stderr]
|
|
333
|
+
.filter(Boolean)
|
|
334
|
+
.map(i => i.toString())
|
|
335
|
+
.join('\n')
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function getPnpmConfig(name) {
|
|
339
|
+
let output = execFileSync('pnpm', [
|
|
340
|
+
'config',
|
|
341
|
+
'get',
|
|
342
|
+
name,
|
|
343
|
+
'--json'
|
|
344
|
+
]).toString()
|
|
345
|
+
return output.trim() === 'undefined' ? undefined : JSON.parse(output)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function getPnpmPackageTimes(name) {
|
|
349
|
+
let times
|
|
350
|
+
try {
|
|
351
|
+
times = JSON.parse(
|
|
352
|
+
execFileSync('pnpm', ['info', name, 'time', '--json']).toString()
|
|
353
|
+
)
|
|
354
|
+
} catch (error) /* c8 ignore start */ {
|
|
355
|
+
throw new BrowserslistUpdateError(
|
|
356
|
+
'Cannot read publication dates of ' +
|
|
357
|
+
name +
|
|
358
|
+
' from pnpm. Refusing to bypass pnpm minimumReleaseAge.\n' +
|
|
359
|
+
commandErrorText(error)
|
|
360
|
+
)
|
|
361
|
+
} /* c8 ignore end */
|
|
362
|
+
if (!times || typeof times !== 'object' || Array.isArray(times)) {
|
|
363
|
+
/* c8 ignore next 6 */
|
|
364
|
+
throw new BrowserslistUpdateError(
|
|
365
|
+
'pnpm returned no publication dates for ' +
|
|
366
|
+
name +
|
|
367
|
+
'. Refusing to bypass pnpm minimumReleaseAge.'
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
return times
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function getMatureVersion(name, minimumReleaseAge) {
|
|
374
|
+
let cutoff = Date.now() - minimumReleaseAge * 60 * 1000
|
|
375
|
+
let times = getPnpmPackageTimes(name)
|
|
376
|
+
|
|
377
|
+
let mature, matureTime
|
|
378
|
+
for (let version of Object.keys(times)) {
|
|
379
|
+
let time = Date.parse(times[version])
|
|
380
|
+
if (!/^\d+\.\d+\.\d+$/.test(version) || !(time <= cutoff)) continue
|
|
381
|
+
if (matureTime === undefined || time > matureTime) {
|
|
382
|
+
mature = version
|
|
383
|
+
matureTime = time
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (!mature) {
|
|
388
|
+
throw new BrowserslistUpdateError(
|
|
389
|
+
'Cannot find a ' +
|
|
390
|
+
name +
|
|
391
|
+
' version old enough for pnpm minimumReleaseAge (' +
|
|
392
|
+
minimumReleaseAge +
|
|
393
|
+
' minutes). Wait for a release to pass the age gate and try again.'
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return mature
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function restoreFile(file, original) {
|
|
401
|
+
if (original === undefined) {
|
|
402
|
+
if (existsSync(file)) unlinkSync(file)
|
|
403
|
+
} else {
|
|
404
|
+
writeFileSync(file, original)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function updatePnpmStrict(print, lock, packages) {
|
|
409
|
+
let minimumReleaseAge = getPnpmConfig('minimumReleaseAge')
|
|
410
|
+
if (
|
|
411
|
+
typeof minimumReleaseAge !== 'number' ||
|
|
412
|
+
!Number.isFinite(minimumReleaseAge) ||
|
|
413
|
+
minimumReleaseAge <= 0
|
|
414
|
+
) {
|
|
415
|
+
throw new BrowserslistUpdateError(
|
|
416
|
+
'Cannot read a valid pnpm minimumReleaseAge. Refusing to disable pnpm security checks.'
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
let versions = {}
|
|
421
|
+
for (let name of packages) {
|
|
422
|
+
versions[name] = getMatureVersion(name, minimumReleaseAge)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
let originalOverrides = getPnpmConfig('overrides')
|
|
426
|
+
if (
|
|
427
|
+
originalOverrides === undefined ||
|
|
428
|
+
originalOverrides === null ||
|
|
429
|
+
Array.isArray(originalOverrides) ||
|
|
430
|
+
typeof originalOverrides !== 'object'
|
|
431
|
+
) {
|
|
432
|
+
originalOverrides = {}
|
|
433
|
+
}
|
|
434
|
+
let temporaryOverrides = { ...originalOverrides, ...versions }
|
|
435
|
+
let packageDir = dirname(lock.file)
|
|
436
|
+
let workspaceFile = join(packageDir, 'pnpm-workspace.yaml')
|
|
437
|
+
let originalWorkspace = existsSync(workspaceFile)
|
|
438
|
+
? readFileSync(workspaceFile)
|
|
439
|
+
: undefined
|
|
440
|
+
let originalLockfile = readFileSync(lock.file)
|
|
441
|
+
let command = 'pnpm config set overrides'
|
|
442
|
+
|
|
443
|
+
print(
|
|
444
|
+
'Strict pnpm minimumReleaseAge detected\n' +
|
|
445
|
+
'Latest policy-compliant: ' +
|
|
446
|
+
pico.bold(pico.green(versions['caniuse-lite'])) +
|
|
447
|
+
'\n' +
|
|
448
|
+
Object.keys(versions)
|
|
449
|
+
.filter(name => name !== 'caniuse-lite')
|
|
450
|
+
.map(name => ' ' + name + ': ' + versions[name] + '\n')
|
|
451
|
+
.join('')
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
execFileSync(
|
|
456
|
+
'pnpm',
|
|
457
|
+
[
|
|
458
|
+
'config',
|
|
459
|
+
'set',
|
|
460
|
+
'overrides',
|
|
461
|
+
JSON.stringify(temporaryOverrides),
|
|
462
|
+
'--json',
|
|
463
|
+
'--location',
|
|
464
|
+
'project'
|
|
465
|
+
],
|
|
466
|
+
{ cwd: packageDir }
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
command = 'pnpm install --lockfile-only'
|
|
470
|
+
print(
|
|
471
|
+
'Updating caniuse-lite version\n' +
|
|
472
|
+
pico.yellow('$ ' + command) +
|
|
473
|
+
' (with temporary policy-compliant overrides)\n'
|
|
474
|
+
)
|
|
475
|
+
execFileSync('pnpm', ['install', '--lockfile-only'], { cwd: packageDir })
|
|
476
|
+
|
|
477
|
+
restoreFile(workspaceFile, originalWorkspace)
|
|
478
|
+
// The lockfile no longer matches the restored overrides, and pnpm
|
|
479
|
+
// freezes the lockfile by default in CI
|
|
480
|
+
command = 'pnpm install --no-frozen-lockfile'
|
|
481
|
+
print(
|
|
482
|
+
'Removing temporary pnpm overrides\n' + pico.yellow('$ ' + command) + '\n'
|
|
483
|
+
)
|
|
484
|
+
execFileSync('pnpm', ['install', '--no-frozen-lockfile'], {
|
|
485
|
+
cwd: packageDir
|
|
486
|
+
})
|
|
487
|
+
} catch (error) /* c8 ignore start */ {
|
|
488
|
+
restoreFile(workspaceFile, originalWorkspace)
|
|
489
|
+
writeFileSync(lock.file, originalLockfile)
|
|
490
|
+
print(pico.red(commandErrorText(error)))
|
|
491
|
+
print(
|
|
492
|
+
pico.red('\n\nProblem with `' + command + '` call. Run it manually.\n')
|
|
493
|
+
)
|
|
494
|
+
process.exit(1)
|
|
495
|
+
} /* c8 ignore end */
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function updatePnpm(print, lock) {
|
|
499
|
+
let lockContent = readFileSync(lock.file).toString()
|
|
500
|
+
let packages = lockContent.includes('baseline-browser-mapping')
|
|
501
|
+
? ['caniuse-lite', 'baseline-browser-mapping']
|
|
502
|
+
: ['caniuse-lite']
|
|
503
|
+
let command = 'pnpm up --depth=9999 --no-save ' + packages.join(' ')
|
|
504
|
+
|
|
505
|
+
print('Updating caniuse-lite version\n' + pico.yellow('$ ' + command) + '\n')
|
|
506
|
+
try {
|
|
507
|
+
execFileSync('pnpm', ['up', '--depth=9999', '--no-save', ...packages], {
|
|
508
|
+
stdio: 'pipe'
|
|
509
|
+
})
|
|
510
|
+
} catch (error) /* c8 ignore start */ {
|
|
511
|
+
let text = commandErrorText(error)
|
|
512
|
+
if (text.includes('ERR_PNPM_STRICT_MIN_RELEASE_AGE_REQUIRES_SAVE')) {
|
|
513
|
+
updatePnpmStrict(print, lock, packages)
|
|
514
|
+
} else {
|
|
515
|
+
print(pico.red(text))
|
|
516
|
+
print(
|
|
517
|
+
pico.red('\n\nProblem with `' + command + '` call. Run it manually.\n')
|
|
518
|
+
)
|
|
519
|
+
process.exit(1)
|
|
520
|
+
}
|
|
521
|
+
} /* c8 ignore end */
|
|
522
|
+
}
|
|
523
|
+
|
|
316
524
|
function updateWith(print, cmd, message = 'Updating caniuse-lite version') {
|
|
317
525
|
print(message + '\n' + pico.yellow('$ ' + cmd) + '\n')
|
|
318
526
|
try {
|
|
@@ -346,16 +554,14 @@ module.exports = function updateDB(print = defaultPrint) {
|
|
|
346
554
|
listError = e
|
|
347
555
|
}
|
|
348
556
|
|
|
349
|
-
print(
|
|
557
|
+
print(
|
|
558
|
+
'Registry latest: ' + pico.bold(pico.green(latest.version)) + '\n'
|
|
559
|
+
)
|
|
350
560
|
|
|
351
561
|
if (lock.mode === 'yarn' && lock.version !== 1) {
|
|
352
562
|
updateWith(print, YARN_CMD + ' up -R caniuse-lite baseline-browser-mapping')
|
|
353
563
|
} else if (lock.mode === 'pnpm') {
|
|
354
|
-
|
|
355
|
-
let packages = lockContent.includes('baseline-browser-mapping')
|
|
356
|
-
? 'caniuse-lite baseline-browser-mapping'
|
|
357
|
-
: 'caniuse-lite'
|
|
358
|
-
updateWith(print, 'pnpm up --depth=Infinity --no-save ' + packages)
|
|
564
|
+
updatePnpm(print, lock)
|
|
359
565
|
} else if (lock.mode === 'bun') {
|
|
360
566
|
updateBun(print, lock, latest)
|
|
361
567
|
} else if (lock.mode === 'deno') {
|