@vercel/build-utils 8.3.7 → 8.3.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 8.3.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Provide help when users get ERR_PNPM_UNSUPPORTED_ENGINE errors without corepack ([#12034](https://github.com/vercel/vercel/pull/12034))
8
+
9
+ - Fix package-manager-warning-1 to happen only happen in correct cases ([#12050](https://github.com/vercel/vercel/pull/12050))
10
+
11
+ ## 8.3.8
12
+
13
+ ### Patch Changes
14
+
15
+ - Limit `package.json#packageManager` parsing to concrete versions ([#12025](https://github.com/vercel/vercel/pull/12025))
16
+
17
+ - Catch PNPM_UNSUPPORTED_ENGINE when corepack is enabled and throw a more helpful error ([#12017](https://github.com/vercel/vercel/pull/12017))
18
+
3
19
  ## 8.3.7
4
20
 
5
21
  ### Patch Changes
@@ -82,7 +82,7 @@ export declare function runNpmInstall(destPath: string, args?: string[], spawnOp
82
82
  * Prepares the input environment based on the used package manager and lockfile
83
83
  * versions.
84
84
  */
85
- export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, nodeVersion, env, }: {
85
+ export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, nodeVersion, env, packageJsonEngines, }: {
86
86
  cliType: CliType;
87
87
  lockfileVersion: number | undefined;
88
88
  packageJsonPackageManager?: string | undefined;
@@ -90,6 +90,7 @@ export declare function getEnvForPackageManager({ cliType, lockfileVersion, pack
90
90
  env: {
91
91
  [x: string]: string | undefined;
92
92
  };
93
+ packageJsonEngines?: PackageJson.Engines;
93
94
  }): {
94
95
  [x: string]: string | undefined;
95
96
  };
@@ -97,12 +98,13 @@ export declare function getEnvForPackageManager({ cliType, lockfileVersion, pack
97
98
  * Helper to get the binary paths that link to the used package manager.
98
99
  * Note: Make sure it doesn't contain any `console.log` calls.
99
100
  */
100
- export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, }: {
101
+ export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, packageJsonEngines, }: {
101
102
  cliType: CliType;
102
103
  lockfileVersion: number | undefined;
103
104
  corepackPackageManager: string | undefined;
104
105
  nodeVersion: NodeVersion | undefined;
105
106
  corepackEnabled?: boolean;
107
+ packageJsonEngines?: PackageJson.Engines;
106
108
  }): {
107
109
  /**
108
110
  * Which lockfile was detected.
@@ -122,10 +124,22 @@ export declare function detectPackageManager(cliType: CliType, lockfileVersion:
122
124
  path: string;
123
125
  detectedLockfile: string;
124
126
  detectedPackageManager: string;
127
+ pnpmVersionRange: string;
125
128
  } | {
126
129
  path: undefined;
127
130
  detectedLockfile: string;
128
131
  detectedPackageManager: string;
132
+ pnpmVersionRange: string;
133
+ } | {
134
+ path: string;
135
+ detectedLockfile: string;
136
+ detectedPackageManager: string;
137
+ pnpmVersionRange?: undefined;
138
+ } | {
139
+ path: undefined;
140
+ detectedLockfile: string;
141
+ detectedPackageManager: string;
142
+ pnpmVersionRange?: undefined;
129
143
  } | undefined;
130
144
  /**
131
145
  * Helper to get the binary paths that link to the used package manager.
@@ -369,7 +369,8 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
369
369
  lockfileVersion,
370
370
  packageJsonPackageManager: packageJson?.packageManager,
371
371
  nodeVersion,
372
- env
372
+ env,
373
+ packageJsonEngines: packageJson?.engines
373
374
  });
374
375
  let commandArgs;
375
376
  const isPotentiallyBrokenNpm = cliType === "npm" && (nodeVersion?.major === 16 || opts.env.PATH?.includes("/node16/bin-npm7")) && !args.includes("--legacy-peer-deps") && spawnOpts?.env?.ENABLE_EXPERIMENTAL_COREPACK !== "1";
@@ -421,7 +422,8 @@ function getEnvForPackageManager({
421
422
  lockfileVersion,
422
423
  packageJsonPackageManager,
423
424
  nodeVersion,
424
- env
425
+ env,
426
+ packageJsonEngines
425
427
  }) {
426
428
  const corepackEnabled = usingCorepack(env, packageJsonPackageManager);
427
429
  const {
@@ -433,7 +435,8 @@ function getEnvForPackageManager({
433
435
  lockfileVersion,
434
436
  corepackPackageManager: packageJsonPackageManager,
435
437
  nodeVersion,
436
- corepackEnabled
438
+ corepackEnabled,
439
+ packageJsonEngines
437
440
  });
438
441
  if (corepackEnabled) {
439
442
  (0, import_debug.default)(
@@ -516,24 +519,40 @@ function getPathOverrideForPackageManager({
516
519
  cliType,
517
520
  lockfileVersion,
518
521
  corepackPackageManager,
519
- corepackEnabled = true
522
+ corepackEnabled = true,
523
+ packageJsonEngines
520
524
  }) {
521
525
  const detectedPackageManger = detectPackageManager(cliType, lockfileVersion);
522
526
  if (!corepackPackageManager || !corepackEnabled) {
527
+ if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
528
+ checkEnginesPnpmAgainstDetected(
529
+ packageJsonEngines.pnpm,
530
+ detectedPackageManger
531
+ );
532
+ }
523
533
  return detectedPackageManger ?? NO_OVERRIDE;
524
534
  }
525
- if (!validateCorepackPackageManager(
535
+ validateCorepackPackageManager(
526
536
  cliType,
527
537
  lockfileVersion,
528
- corepackPackageManager
529
- )) {
530
- console.warn(
531
- `WARN [package-manager-warning-1] Detected lockfile "${lockfileVersion}" which is not compatible with the intended corepack package manager "${corepackPackageManager}". Update your lockfile or change to a compatible corepack version.`
532
- );
533
- }
538
+ corepackPackageManager,
539
+ packageJsonEngines?.pnpm
540
+ );
534
541
  return NO_OVERRIDE;
535
542
  }
536
- function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackageManager) {
543
+ function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
544
+ if (detectedPackageManger?.pnpmVersionRange && (0, import_semver.validRange)(detectedPackageManger.pnpmVersionRange) && (0, import_semver.validRange)(enginesPnpm)) {
545
+ if (!(0, import_semver.intersects)(detectedPackageManger.pnpmVersionRange, enginesPnpm)) {
546
+ throw new Error(
547
+ `Detected pnpm "${detectedPackageManger.pnpmVersionRange}" is not compatible with the engines.pnpm "${enginesPnpm}" in your package.json. Either enable corepack with a valid package.json#packageManager value (https://vercel.com/docs/deployments/configure-a-build#corepack) or remove your package.json#engines.pnpm.`
548
+ );
549
+ }
550
+ }
551
+ console.warn(
552
+ `Using package.json#engines.pnpm without corepack and package.json#packageManager could lead to failed builds with ERR_PNPM_UNSUPPORTED_ENGINE. Learn more: https://vercel.com/docs/errors/error-list#pnpm-engine-unsupported`
553
+ );
554
+ }
555
+ function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackageManager, enginesPnpmVersionRange) {
537
556
  const validatedCorepackPackageManager = validateVersionSpecifier(
538
557
  corepackPackageManager
539
558
  );
@@ -541,27 +560,36 @@ function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackag
541
560
  console.warn(
542
561
  `WARN [package-manager-warning-2] Intended corepack defined package manager "${corepackPackageManager}" is not a valid semver value.`
543
562
  );
544
- return false;
563
+ return;
545
564
  }
546
565
  if (cliType !== validatedCorepackPackageManager.packageName) {
547
566
  console.warn(
548
567
  `WARN [package-manager-warning-3] Detected package manager "${cliType}" does not match intended corepack defined package manager "${validatedCorepackPackageManager.packageName}". Change your lockfile or "package.json#packageManager" value to match.`
549
568
  );
550
- return false;
569
+ return;
551
570
  }
552
- const corepackPackageManagerVersion = (0, import_semver.coerce)(
553
- validatedCorepackPackageManager.packageVersionRange
554
- );
555
- if (corepackPackageManagerVersion === null) {
556
- return true;
557
- } else if (lockfileVersion) {
558
- return validLockfileForPackageManager(
571
+ if (cliType === "pnpm" && enginesPnpmVersionRange) {
572
+ const pnpmWithinEngineRange = (0, import_semver.satisfies)(
573
+ validatedCorepackPackageManager.packageVersion,
574
+ enginesPnpmVersionRange
575
+ );
576
+ if (!pnpmWithinEngineRange) {
577
+ throw new Error(
578
+ `The version of pnpm specified in package.json#packageManager (${validatedCorepackPackageManager.packageVersion}) must satisfy the version range in package.json#engines.pnpm (${enginesPnpmVersionRange}).`
579
+ );
580
+ }
581
+ }
582
+ if (lockfileVersion) {
583
+ const lockfileValid = validLockfileForPackageManager(
559
584
  cliType,
560
585
  lockfileVersion,
561
- corepackPackageManagerVersion
586
+ validatedCorepackPackageManager.packageVersion
562
587
  );
563
- } else {
564
- return true;
588
+ if (!lockfileValid) {
589
+ console.warn(
590
+ `WARN [package-manager-warning-1] Detected lockfile "${lockfileVersion}" which is not compatible with the intended corepack package manager "${corepackPackageManager}". Update your lockfile or change to a compatible corepack version.`
591
+ );
592
+ }
565
593
  }
566
594
  }
567
595
  function validateVersionSpecifier(version) {
@@ -578,12 +606,13 @@ function validateVersionSpecifier(version) {
578
606
  if (!after) {
579
607
  return void 0;
580
608
  }
581
- if (!(0, import_semver.validRange)(after)) {
609
+ const packageVersion = (0, import_semver.parse)(after);
610
+ if (!packageVersion) {
582
611
  return void 0;
583
612
  }
584
613
  return {
585
614
  packageName: before,
586
- packageVersionRange: after
615
+ packageVersion
587
616
  };
588
617
  }
589
618
  function detectPackageManager(cliType, lockfileVersion) {
@@ -596,26 +625,30 @@ function detectPackageManager(cliType, lockfileVersion) {
596
625
  return {
597
626
  path: "/pnpm7/node_modules/.bin",
598
627
  detectedLockfile: "pnpm-lock.yaml",
599
- detectedPackageManager: "pnpm@7.x"
628
+ detectedPackageManager: "pnpm@7.x",
629
+ pnpmVersionRange: "7.x"
600
630
  };
601
631
  case "pnpm 8":
602
632
  return {
603
633
  path: "/pnpm8/node_modules/.bin",
604
634
  detectedLockfile: "pnpm-lock.yaml",
605
- detectedPackageManager: "pnpm@8.x"
635
+ detectedPackageManager: "pnpm@8.x",
636
+ pnpmVersionRange: "8.x"
606
637
  };
607
638
  case "pnpm 9":
608
639
  return {
609
640
  path: "/pnpm9/node_modules/.bin",
610
641
  detectedLockfile: "pnpm-lock.yaml",
611
- detectedPackageManager: "pnpm@9.x"
642
+ detectedPackageManager: "pnpm@9.x",
643
+ pnpmVersionRange: "9.x"
612
644
  };
613
645
  case "pnpm 6":
614
646
  return {
615
647
  // undefined because pnpm@6 is the current default in the build container
616
648
  path: void 0,
617
649
  detectedLockfile: "pnpm-lock.yaml",
618
- detectedPackageManager: "pnpm@6.x"
650
+ detectedPackageManager: "pnpm@6.x",
651
+ pnpmVersionRange: "6.x"
619
652
  };
620
653
  default:
621
654
  return void 0;
@@ -684,7 +717,8 @@ async function runCustomInstallCommand({
684
717
  lockfileVersion,
685
718
  packageJsonPackageManager: packageJson?.packageManager,
686
719
  nodeVersion,
687
- env: spawnOpts?.env || {}
720
+ env: spawnOpts?.env || {},
721
+ packageJsonEngines: packageJson?.engines
688
722
  });
689
723
  (0, import_debug.default)(`Running with $PATH:`, env?.PATH || "");
690
724
  await execCommand(installCommand, {
@@ -715,7 +749,8 @@ async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
715
749
  lockfileVersion,
716
750
  packageJsonPackageManager: packageJson?.packageManager,
717
751
  nodeVersion: void 0,
718
- env: (0, import_clone_env.cloneEnv)(process.env, spawnOpts?.env)
752
+ env: (0, import_clone_env.cloneEnv)(process.env, spawnOpts?.env),
753
+ packageJsonEngines: packageJson?.engines
719
754
  })
720
755
  };
721
756
  if (cliType === "npm") {
package/dist/index.js CHANGED
@@ -9994,9 +9994,9 @@ var require_minimatch = __commonJS({
9994
9994
  throw new TypeError("pattern is too long");
9995
9995
  }
9996
9996
  };
9997
- Minimatch.prototype.parse = parse2;
9997
+ Minimatch.prototype.parse = parse3;
9998
9998
  var SUBPARSE = {};
9999
- function parse2(pattern, isSub) {
9999
+ function parse3(pattern, isSub) {
10000
10000
  assertValidPattern(pattern);
10001
10001
  var options = this.options;
10002
10002
  if (pattern === "**") {
@@ -13197,8 +13197,8 @@ var require_semver = __commonJS({
13197
13197
  }
13198
13198
  }
13199
13199
  var i;
13200
- exports2.parse = parse2;
13201
- function parse2(version, options) {
13200
+ exports2.parse = parse3;
13201
+ function parse3(version, options) {
13202
13202
  if (!options || typeof options !== "object") {
13203
13203
  options = {
13204
13204
  loose: !!options,
@@ -13226,12 +13226,12 @@ var require_semver = __commonJS({
13226
13226
  }
13227
13227
  exports2.valid = valid;
13228
13228
  function valid(version, options) {
13229
- var v = parse2(version, options);
13229
+ var v = parse3(version, options);
13230
13230
  return v ? v.version : null;
13231
13231
  }
13232
13232
  exports2.clean = clean;
13233
13233
  function clean(version, options) {
13234
- var s = parse2(version.trim().replace(/^[=v]+/, ""), options);
13234
+ var s = parse3(version.trim().replace(/^[=v]+/, ""), options);
13235
13235
  return s ? s.version : null;
13236
13236
  }
13237
13237
  exports2.SemVer = SemVer2;
@@ -13441,8 +13441,8 @@ var require_semver = __commonJS({
13441
13441
  if (eq(version1, version2)) {
13442
13442
  return null;
13443
13443
  } else {
13444
- var v1 = parse2(version1);
13445
- var v2 = parse2(version2);
13444
+ var v1 = parse3(version1);
13445
+ var v2 = parse3(version2);
13446
13446
  var prefix = "";
13447
13447
  if (v1.prerelease.length || v2.prerelease.length) {
13448
13448
  prefix = "pre";
@@ -13639,10 +13639,10 @@ var require_semver = __commonJS({
13639
13639
  var rangeTmp;
13640
13640
  if (this.operator === "") {
13641
13641
  rangeTmp = new Range(comp.value, options);
13642
- return satisfies(this.value, rangeTmp, options);
13642
+ return satisfies2(this.value, rangeTmp, options);
13643
13643
  } else if (comp.operator === "") {
13644
13644
  rangeTmp = new Range(this.value, options);
13645
- return satisfies(comp.semver, rangeTmp, options);
13645
+ return satisfies2(comp.semver, rangeTmp, options);
13646
13646
  }
13647
13647
  var sameDirectionIncreasing = (this.operator === ">=" || this.operator === ">") && (comp.operator === ">=" || comp.operator === ">");
13648
13648
  var sameDirectionDecreasing = (this.operator === "<=" || this.operator === "<") && (comp.operator === "<=" || comp.operator === "<");
@@ -13951,8 +13951,8 @@ var require_semver = __commonJS({
13951
13951
  }
13952
13952
  return true;
13953
13953
  }
13954
- exports2.satisfies = satisfies;
13955
- function satisfies(version, range, options) {
13954
+ exports2.satisfies = satisfies2;
13955
+ function satisfies2(version, range, options) {
13956
13956
  try {
13957
13957
  range = new Range(range, options);
13958
13958
  } catch (er) {
@@ -14080,7 +14080,7 @@ var require_semver = __commonJS({
14080
14080
  default:
14081
14081
  throw new TypeError('Must provide a hilo val of "<" or ">"');
14082
14082
  }
14083
- if (satisfies(version, range, options)) {
14083
+ if (satisfies2(version, range, options)) {
14084
14084
  return false;
14085
14085
  }
14086
14086
  for (var i2 = 0; i2 < range.set.length; ++i2) {
@@ -14112,7 +14112,7 @@ var require_semver = __commonJS({
14112
14112
  }
14113
14113
  exports2.prerelease = prerelease;
14114
14114
  function prerelease(version, options) {
14115
- var parsed = parse2(version, options);
14115
+ var parsed = parse3(version, options);
14116
14116
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
14117
14117
  }
14118
14118
  exports2.intersects = intersects3;
@@ -14133,7 +14133,7 @@ var require_semver = __commonJS({
14133
14133
  if (match == null) {
14134
14134
  return null;
14135
14135
  }
14136
- return parse2(match[1] + "." + (match[2] || "0") + "." + (match[3] || "0"));
14136
+ return parse3(match[1] + "." + (match[2] || "0") + "." + (match[3] || "0"));
14137
14137
  }
14138
14138
  }
14139
14139
  });
@@ -14201,7 +14201,7 @@ var require_parse = __commonJS({
14201
14201
  }
14202
14202
  return parsed;
14203
14203
  }
14204
- function parse2(command, args, options) {
14204
+ function parse3(command, args, options) {
14205
14205
  if (args && !Array.isArray(args)) {
14206
14206
  options = args;
14207
14207
  args = null;
@@ -14220,7 +14220,7 @@ var require_parse = __commonJS({
14220
14220
  };
14221
14221
  return options.shell ? parseShell(parsed) : parseNonShell(parsed);
14222
14222
  }
14223
- module2.exports = parse2;
14223
+ module2.exports = parse3;
14224
14224
  }
14225
14225
  });
14226
14226
 
@@ -14279,16 +14279,16 @@ var require_cross_spawn = __commonJS({
14279
14279
  "../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/index.js"(exports2, module2) {
14280
14280
  "use strict";
14281
14281
  var cp = require("child_process");
14282
- var parse2 = require_parse();
14282
+ var parse3 = require_parse();
14283
14283
  var enoent = require_enoent();
14284
14284
  function spawn2(command, args, options) {
14285
- const parsed = parse2(command, args, options);
14285
+ const parsed = parse3(command, args, options);
14286
14286
  const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
14287
14287
  enoent.hookChildProcess(spawned, parsed);
14288
14288
  return spawned;
14289
14289
  }
14290
14290
  function spawnSync(command, args, options) {
14291
- const parsed = parse2(command, args, options);
14291
+ const parsed = parse3(command, args, options);
14292
14292
  const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
14293
14293
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
14294
14294
  return result;
@@ -14296,7 +14296,7 @@ var require_cross_spawn = __commonJS({
14296
14296
  module2.exports = spawn2;
14297
14297
  module2.exports.spawn = spawn2;
14298
14298
  module2.exports.sync = spawnSync;
14299
- module2.exports._parse = parse2;
14299
+ module2.exports._parse = parse3;
14300
14300
  module2.exports._enoent = enoent;
14301
14301
  }
14302
14302
  });
@@ -14438,8 +14438,8 @@ var require_semver2 = __commonJS({
14438
14438
  }
14439
14439
  }
14440
14440
  var i;
14441
- exports2.parse = parse2;
14442
- function parse2(version, options) {
14441
+ exports2.parse = parse3;
14442
+ function parse3(version, options) {
14443
14443
  if (!options || typeof options !== "object") {
14444
14444
  options = {
14445
14445
  loose: !!options,
@@ -14467,12 +14467,12 @@ var require_semver2 = __commonJS({
14467
14467
  }
14468
14468
  exports2.valid = valid;
14469
14469
  function valid(version, options) {
14470
- var v = parse2(version, options);
14470
+ var v = parse3(version, options);
14471
14471
  return v ? v.version : null;
14472
14472
  }
14473
14473
  exports2.clean = clean;
14474
14474
  function clean(version, options) {
14475
- var s = parse2(version.trim().replace(/^[=v]+/, ""), options);
14475
+ var s = parse3(version.trim().replace(/^[=v]+/, ""), options);
14476
14476
  return s ? s.version : null;
14477
14477
  }
14478
14478
  exports2.SemVer = SemVer2;
@@ -14704,8 +14704,8 @@ var require_semver2 = __commonJS({
14704
14704
  if (eq(version1, version2)) {
14705
14705
  return null;
14706
14706
  } else {
14707
- var v1 = parse2(version1);
14708
- var v2 = parse2(version2);
14707
+ var v1 = parse3(version1);
14708
+ var v2 = parse3(version2);
14709
14709
  var prefix = "";
14710
14710
  if (v1.prerelease.length || v2.prerelease.length) {
14711
14711
  prefix = "pre";
@@ -14915,13 +14915,13 @@ var require_semver2 = __commonJS({
14915
14915
  return true;
14916
14916
  }
14917
14917
  rangeTmp = new Range(comp.value, options);
14918
- return satisfies(this.value, rangeTmp, options);
14918
+ return satisfies2(this.value, rangeTmp, options);
14919
14919
  } else if (comp.operator === "") {
14920
14920
  if (comp.value === "") {
14921
14921
  return true;
14922
14922
  }
14923
14923
  rangeTmp = new Range(this.value, options);
14924
- return satisfies(comp.semver, rangeTmp, options);
14924
+ return satisfies2(comp.semver, rangeTmp, options);
14925
14925
  }
14926
14926
  var sameDirectionIncreasing = (this.operator === ">=" || this.operator === ">") && (comp.operator === ">=" || comp.operator === ">");
14927
14927
  var sameDirectionDecreasing = (this.operator === "<=" || this.operator === "<") && (comp.operator === "<=" || comp.operator === "<");
@@ -15248,8 +15248,8 @@ var require_semver2 = __commonJS({
15248
15248
  }
15249
15249
  return true;
15250
15250
  }
15251
- exports2.satisfies = satisfies;
15252
- function satisfies(version, range, options) {
15251
+ exports2.satisfies = satisfies2;
15252
+ function satisfies2(version, range, options) {
15253
15253
  try {
15254
15254
  range = new Range(range, options);
15255
15255
  } catch (er) {
@@ -15377,7 +15377,7 @@ var require_semver2 = __commonJS({
15377
15377
  default:
15378
15378
  throw new TypeError('Must provide a hilo val of "<" or ">"');
15379
15379
  }
15380
- if (satisfies(version, range, options)) {
15380
+ if (satisfies2(version, range, options)) {
15381
15381
  return false;
15382
15382
  }
15383
15383
  for (var i2 = 0; i2 < range.set.length; ++i2) {
@@ -15409,7 +15409,7 @@ var require_semver2 = __commonJS({
15409
15409
  }
15410
15410
  exports2.prerelease = prerelease;
15411
15411
  function prerelease(version, options) {
15412
- var parsed = parse2(version, options);
15412
+ var parsed = parse3(version, options);
15413
15413
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
15414
15414
  }
15415
15415
  exports2.intersects = intersects3;
@@ -15446,7 +15446,7 @@ var require_semver2 = __commonJS({
15446
15446
  if (match === null) {
15447
15447
  return null;
15448
15448
  }
15449
- return parse2(match[2] + "." + (match[3] || "0") + "." + (match[4] || "0"), options);
15449
+ return parse3(match[2] + "." + (match[3] || "0") + "." + (match[4] || "0"), options);
15450
15450
  }
15451
15451
  }
15452
15452
  });
@@ -22090,7 +22090,8 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
22090
22090
  lockfileVersion,
22091
22091
  packageJsonPackageManager: packageJson?.packageManager,
22092
22092
  nodeVersion,
22093
- env
22093
+ env,
22094
+ packageJsonEngines: packageJson?.engines
22094
22095
  });
22095
22096
  let commandArgs;
22096
22097
  const isPotentiallyBrokenNpm = cliType === "npm" && (nodeVersion?.major === 16 || opts.env.PATH?.includes("/node16/bin-npm7")) && !args.includes("--legacy-peer-deps") && spawnOpts?.env?.ENABLE_EXPERIMENTAL_COREPACK !== "1";
@@ -22142,7 +22143,8 @@ function getEnvForPackageManager({
22142
22143
  lockfileVersion,
22143
22144
  packageJsonPackageManager,
22144
22145
  nodeVersion,
22145
- env
22146
+ env,
22147
+ packageJsonEngines
22146
22148
  }) {
22147
22149
  const corepackEnabled = usingCorepack(env, packageJsonPackageManager);
22148
22150
  const {
@@ -22154,7 +22156,8 @@ function getEnvForPackageManager({
22154
22156
  lockfileVersion,
22155
22157
  corepackPackageManager: packageJsonPackageManager,
22156
22158
  nodeVersion,
22157
- corepackEnabled
22159
+ corepackEnabled,
22160
+ packageJsonEngines
22158
22161
  });
22159
22162
  if (corepackEnabled) {
22160
22163
  debug(
@@ -22237,24 +22240,40 @@ function getPathOverrideForPackageManager({
22237
22240
  cliType,
22238
22241
  lockfileVersion,
22239
22242
  corepackPackageManager,
22240
- corepackEnabled = true
22243
+ corepackEnabled = true,
22244
+ packageJsonEngines
22241
22245
  }) {
22242
22246
  const detectedPackageManger = detectPackageManager(cliType, lockfileVersion);
22243
22247
  if (!corepackPackageManager || !corepackEnabled) {
22248
+ if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
22249
+ checkEnginesPnpmAgainstDetected(
22250
+ packageJsonEngines.pnpm,
22251
+ detectedPackageManger
22252
+ );
22253
+ }
22244
22254
  return detectedPackageManger ?? NO_OVERRIDE;
22245
22255
  }
22246
- if (!validateCorepackPackageManager(
22256
+ validateCorepackPackageManager(
22247
22257
  cliType,
22248
22258
  lockfileVersion,
22249
- corepackPackageManager
22250
- )) {
22251
- console.warn(
22252
- `WARN [package-manager-warning-1] Detected lockfile "${lockfileVersion}" which is not compatible with the intended corepack package manager "${corepackPackageManager}". Update your lockfile or change to a compatible corepack version.`
22253
- );
22254
- }
22259
+ corepackPackageManager,
22260
+ packageJsonEngines?.pnpm
22261
+ );
22255
22262
  return NO_OVERRIDE;
22256
22263
  }
22257
- function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackageManager) {
22264
+ function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
22265
+ if (detectedPackageManger?.pnpmVersionRange && (0, import_semver2.validRange)(detectedPackageManger.pnpmVersionRange) && (0, import_semver2.validRange)(enginesPnpm)) {
22266
+ if (!(0, import_semver2.intersects)(detectedPackageManger.pnpmVersionRange, enginesPnpm)) {
22267
+ throw new Error(
22268
+ `Detected pnpm "${detectedPackageManger.pnpmVersionRange}" is not compatible with the engines.pnpm "${enginesPnpm}" in your package.json. Either enable corepack with a valid package.json#packageManager value (https://vercel.com/docs/deployments/configure-a-build#corepack) or remove your package.json#engines.pnpm.`
22269
+ );
22270
+ }
22271
+ }
22272
+ console.warn(
22273
+ `Using package.json#engines.pnpm without corepack and package.json#packageManager could lead to failed builds with ERR_PNPM_UNSUPPORTED_ENGINE. Learn more: https://vercel.com/docs/errors/error-list#pnpm-engine-unsupported`
22274
+ );
22275
+ }
22276
+ function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackageManager, enginesPnpmVersionRange) {
22258
22277
  const validatedCorepackPackageManager = validateVersionSpecifier(
22259
22278
  corepackPackageManager
22260
22279
  );
@@ -22262,27 +22281,36 @@ function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackag
22262
22281
  console.warn(
22263
22282
  `WARN [package-manager-warning-2] Intended corepack defined package manager "${corepackPackageManager}" is not a valid semver value.`
22264
22283
  );
22265
- return false;
22284
+ return;
22266
22285
  }
22267
22286
  if (cliType !== validatedCorepackPackageManager.packageName) {
22268
22287
  console.warn(
22269
22288
  `WARN [package-manager-warning-3] Detected package manager "${cliType}" does not match intended corepack defined package manager "${validatedCorepackPackageManager.packageName}". Change your lockfile or "package.json#packageManager" value to match.`
22270
22289
  );
22271
- return false;
22290
+ return;
22272
22291
  }
22273
- const corepackPackageManagerVersion = (0, import_semver2.coerce)(
22274
- validatedCorepackPackageManager.packageVersionRange
22275
- );
22276
- if (corepackPackageManagerVersion === null) {
22277
- return true;
22278
- } else if (lockfileVersion) {
22279
- return validLockfileForPackageManager(
22292
+ if (cliType === "pnpm" && enginesPnpmVersionRange) {
22293
+ const pnpmWithinEngineRange = (0, import_semver2.satisfies)(
22294
+ validatedCorepackPackageManager.packageVersion,
22295
+ enginesPnpmVersionRange
22296
+ );
22297
+ if (!pnpmWithinEngineRange) {
22298
+ throw new Error(
22299
+ `The version of pnpm specified in package.json#packageManager (${validatedCorepackPackageManager.packageVersion}) must satisfy the version range in package.json#engines.pnpm (${enginesPnpmVersionRange}).`
22300
+ );
22301
+ }
22302
+ }
22303
+ if (lockfileVersion) {
22304
+ const lockfileValid = validLockfileForPackageManager(
22280
22305
  cliType,
22281
22306
  lockfileVersion,
22282
- corepackPackageManagerVersion
22307
+ validatedCorepackPackageManager.packageVersion
22283
22308
  );
22284
- } else {
22285
- return true;
22309
+ if (!lockfileValid) {
22310
+ console.warn(
22311
+ `WARN [package-manager-warning-1] Detected lockfile "${lockfileVersion}" which is not compatible with the intended corepack package manager "${corepackPackageManager}". Update your lockfile or change to a compatible corepack version.`
22312
+ );
22313
+ }
22286
22314
  }
22287
22315
  }
22288
22316
  function validateVersionSpecifier(version) {
@@ -22299,12 +22327,13 @@ function validateVersionSpecifier(version) {
22299
22327
  if (!after) {
22300
22328
  return void 0;
22301
22329
  }
22302
- if (!(0, import_semver2.validRange)(after)) {
22330
+ const packageVersion = (0, import_semver2.parse)(after);
22331
+ if (!packageVersion) {
22303
22332
  return void 0;
22304
22333
  }
22305
22334
  return {
22306
22335
  packageName: before,
22307
- packageVersionRange: after
22336
+ packageVersion
22308
22337
  };
22309
22338
  }
22310
22339
  function detectPackageManager(cliType, lockfileVersion) {
@@ -22317,26 +22346,30 @@ function detectPackageManager(cliType, lockfileVersion) {
22317
22346
  return {
22318
22347
  path: "/pnpm7/node_modules/.bin",
22319
22348
  detectedLockfile: "pnpm-lock.yaml",
22320
- detectedPackageManager: "pnpm@7.x"
22349
+ detectedPackageManager: "pnpm@7.x",
22350
+ pnpmVersionRange: "7.x"
22321
22351
  };
22322
22352
  case "pnpm 8":
22323
22353
  return {
22324
22354
  path: "/pnpm8/node_modules/.bin",
22325
22355
  detectedLockfile: "pnpm-lock.yaml",
22326
- detectedPackageManager: "pnpm@8.x"
22356
+ detectedPackageManager: "pnpm@8.x",
22357
+ pnpmVersionRange: "8.x"
22327
22358
  };
22328
22359
  case "pnpm 9":
22329
22360
  return {
22330
22361
  path: "/pnpm9/node_modules/.bin",
22331
22362
  detectedLockfile: "pnpm-lock.yaml",
22332
- detectedPackageManager: "pnpm@9.x"
22363
+ detectedPackageManager: "pnpm@9.x",
22364
+ pnpmVersionRange: "9.x"
22333
22365
  };
22334
22366
  case "pnpm 6":
22335
22367
  return {
22336
22368
  // undefined because pnpm@6 is the current default in the build container
22337
22369
  path: void 0,
22338
22370
  detectedLockfile: "pnpm-lock.yaml",
22339
- detectedPackageManager: "pnpm@6.x"
22371
+ detectedPackageManager: "pnpm@6.x",
22372
+ pnpmVersionRange: "6.x"
22340
22373
  };
22341
22374
  default:
22342
22375
  return void 0;
@@ -22405,7 +22438,8 @@ async function runCustomInstallCommand({
22405
22438
  lockfileVersion,
22406
22439
  packageJsonPackageManager: packageJson?.packageManager,
22407
22440
  nodeVersion,
22408
- env: spawnOpts?.env || {}
22441
+ env: spawnOpts?.env || {},
22442
+ packageJsonEngines: packageJson?.engines
22409
22443
  });
22410
22444
  debug(`Running with $PATH:`, env?.PATH || "");
22411
22445
  await execCommand(installCommand, {
@@ -22436,7 +22470,8 @@ async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
22436
22470
  lockfileVersion,
22437
22471
  packageJsonPackageManager: packageJson?.packageManager,
22438
22472
  nodeVersion: void 0,
22439
- env: cloneEnv(process.env, spawnOpts?.env)
22473
+ env: cloneEnv(process.env, spawnOpts?.env),
22474
+ packageJsonEngines: packageJson?.engines
22440
22475
  })
22441
22476
  };
22442
22477
  if (cliType === "npm") {
package/dist/types.d.ts CHANGED
@@ -236,6 +236,7 @@ export declare namespace PackageJson {
236
236
  interface Engines {
237
237
  node?: string;
238
238
  npm?: string;
239
+ pnpm?: string;
239
240
  }
240
241
  interface PublishConfig {
241
242
  registry?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "8.3.7",
3
+ "version": "8.3.9",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",