@vercel/build-utils 10.1.0 → 10.3.0

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,29 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 10.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Delay pnpm@10 preferred date ([#13100](https://github.com/vercel/vercel/pull/13100))
8
+
9
+ ### Patch Changes
10
+
11
+ - Type-check tests ([#13096](https://github.com/vercel/vercel/pull/13096))
12
+
13
+ ## 10.2.0
14
+
15
+ ### Minor Changes
16
+
17
+ - Detect v9 pnpm lock files as pnpm 10 for new projects ([#13072](https://github.com/vercel/vercel/pull/13072))
18
+
19
+ ### Patch Changes
20
+
21
+ - Improve build log messages surrounding pnpm 10 ([#13088](https://github.com/vercel/vercel/pull/13088))
22
+
23
+ - [build-utils] extract checkIfAlreadyInstalled helper to clarify intent ([#13060](https://github.com/vercel/vercel/pull/13060))
24
+
25
+ - Allow pnpm 10 to use package.json#packageManager without an engines error ([#13083](https://github.com/vercel/vercel/pull/13083))
26
+
3
27
  ## 10.1.0
4
28
 
5
29
  ### Minor Changes
@@ -1,6 +1,7 @@
1
1
  import { NodeVersion } from '../types';
2
2
  export type NodeVersionMajor = ReturnType<typeof getOptions>[number]['major'];
3
3
  export declare const NODE_VERSIONS: NodeVersion[];
4
+ export declare function getNodeVersionByMajor(major: number): NodeVersion | undefined;
4
5
  declare function getOptions(): NodeVersion[];
5
6
  export declare function getAvailableNodeVersions(): NodeVersionMajor[];
6
7
  export declare function getLatestNodeVersion(availableVersions?: NodeVersionMajor[]): NodeVersion;
@@ -32,6 +32,7 @@ __export(node_version_exports, {
32
32
  getAvailableNodeVersions: () => getAvailableNodeVersions,
33
33
  getDiscontinuedNodeVersions: () => getDiscontinuedNodeVersions,
34
34
  getLatestNodeVersion: () => getLatestNodeVersion,
35
+ getNodeVersionByMajor: () => getNodeVersionByMajor,
35
36
  getSupportedNodeVersion: () => getSupportedNodeVersion
36
37
  });
37
38
  module.exports = __toCommonJS(node_version_exports);
@@ -87,6 +88,9 @@ const NODE_VERSIONS = [
87
88
  discontinueDate: /* @__PURE__ */ new Date("2020-01-06")
88
89
  })
89
90
  ];
91
+ function getNodeVersionByMajor(major) {
92
+ return NODE_VERSIONS.find((v) => v.major === major);
93
+ }
90
94
  function getOptions() {
91
95
  return NODE_VERSIONS;
92
96
  }
@@ -176,5 +180,6 @@ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVer
176
180
  getAvailableNodeVersions,
177
181
  getDiscontinuedNodeVersions,
178
182
  getLatestNodeVersion,
183
+ getNodeVersionByMajor,
179
184
  getSupportedNodeVersion
180
185
  });
@@ -92,12 +92,12 @@ export declare function usingCorepack(env: {
92
92
  [x: string]: string | undefined;
93
93
  }, packageJsonPackageManager: string | undefined, turboSupportsCorepackHome: boolean | undefined): boolean;
94
94
  export declare function walkParentDirs({ base, start, filename, }: WalkParentDirsProps): Promise<string | null>;
95
- export declare function runNpmInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta, nodeVersion?: NodeVersion): Promise<boolean>;
95
+ export declare function runNpmInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta, nodeVersion?: NodeVersion, projectCreatedAt?: number): Promise<boolean>;
96
96
  /**
97
97
  * Prepares the input environment based on the used package manager and lockfile
98
98
  * versions.
99
99
  */
100
- export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, nodeVersion, env, packageJsonEngines, turboSupportsCorepackHome, }: {
100
+ export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, nodeVersion, env, packageJsonEngines, turboSupportsCorepackHome, projectCreatedAt, }: {
101
101
  cliType: CliType;
102
102
  lockfileVersion: number | undefined;
103
103
  packageJsonPackageManager?: string | undefined;
@@ -107,20 +107,23 @@ export declare function getEnvForPackageManager({ cliType, lockfileVersion, pack
107
107
  };
108
108
  packageJsonEngines?: PackageJson.Engines;
109
109
  turboSupportsCorepackHome?: boolean | undefined;
110
+ projectCreatedAt?: number | undefined;
110
111
  }): {
111
112
  [x: string]: string | undefined;
112
113
  };
114
+ export declare const PNPM_10_PREFERRED_AT: Date;
113
115
  /**
114
116
  * Helper to get the binary paths that link to the used package manager.
115
117
  * Note: Make sure it doesn't contain any `console.log` calls.
116
118
  */
117
- export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, packageJsonEngines, }: {
119
+ export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, packageJsonEngines, projectCreatedAt, }: {
118
120
  cliType: CliType;
119
121
  lockfileVersion: number | undefined;
120
122
  corepackPackageManager: string | undefined;
121
123
  nodeVersion: NodeVersion | undefined;
122
124
  corepackEnabled?: boolean;
123
125
  packageJsonEngines?: PackageJson.Engines;
126
+ projectCreatedAt?: number;
124
127
  }): {
125
128
  /**
126
129
  * Which lockfile was detected.
@@ -136,7 +139,7 @@ export declare function getPathOverrideForPackageManager({ cliType, lockfileVers
136
139
  */
137
140
  path: string | undefined;
138
141
  };
139
- export declare function detectPackageManager(cliType: CliType, lockfileVersion: number | undefined): {
142
+ export declare function detectPackageManager(cliType: CliType, lockfileVersion: number | undefined, projectCreatedAt?: number): {
140
143
  path: string;
141
144
  detectedLockfile: string;
142
145
  detectedPackageManager: string;
@@ -189,13 +192,14 @@ export declare function getPathForPackageManager({ cliType, lockfileVersion, nod
189
192
  */
190
193
  yarnNodeLinker: string | undefined;
191
194
  };
192
- export declare function runCustomInstallCommand({ destPath, installCommand, nodeVersion, spawnOpts, }: {
195
+ export declare function runCustomInstallCommand({ destPath, installCommand, nodeVersion, spawnOpts, projectCreatedAt, }: {
193
196
  destPath: string;
194
197
  installCommand: string;
195
198
  nodeVersion: NodeVersion;
196
199
  spawnOpts?: SpawnOptions;
200
+ projectCreatedAt?: number;
197
201
  }): Promise<void>;
198
- export declare function runPackageJsonScript(destPath: string, scriptNames: string | Iterable<string>, spawnOpts?: SpawnOptions): Promise<boolean>;
202
+ export declare function runPackageJsonScript(destPath: string, scriptNames: string | Iterable<string>, spawnOpts?: SpawnOptions, projectCreatedAt?: number): Promise<boolean>;
199
203
  export declare function runBundleInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta): Promise<void>;
200
204
  export declare function runPipInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta): Promise<void>;
201
205
  export declare function getScriptName(pkg: Pick<PackageJson, 'scripts'> | null | undefined, possibleNames: Iterable<string>): string | undefined;
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var run_user_scripts_exports = {};
30
30
  __export(run_user_scripts_exports, {
31
+ PNPM_10_PREFERRED_AT: () => PNPM_10_PREFERRED_AT,
31
32
  detectPackageManager: () => detectPackageManager,
32
33
  execCommand: () => execCommand,
33
34
  getEnvForPackageManager: () => getEnvForPackageManager,
@@ -461,8 +462,20 @@ async function runInstallCommand({
461
462
  }
462
463
  await spawnAsync(packageManager, commandArguments, opts);
463
464
  }
465
+ function initializeSet(set) {
466
+ if (!isSet(set)) {
467
+ return /* @__PURE__ */ new Set();
468
+ }
469
+ return set;
470
+ }
471
+ function checkIfAlreadyInstalled(runNpmInstallSet, packageJsonPath) {
472
+ const initializedRunNpmInstallSet = initializeSet(runNpmInstallSet);
473
+ const alreadyInstalled = initializedRunNpmInstallSet.has(packageJsonPath);
474
+ initializedRunNpmInstallSet.add(packageJsonPath);
475
+ return { alreadyInstalled, runNpmInstallSet: initializedRunNpmInstallSet };
476
+ }
464
477
  const runNpmInstallSema = new import_async_sema.default(1);
465
- async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion) {
478
+ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion, projectCreatedAt) {
466
479
  if (meta?.isDev) {
467
480
  (0, import_debug.default)("Skipping dependency installation because dev mode is enabled");
468
481
  return false;
@@ -484,17 +497,16 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
484
497
  );
485
498
  return false;
486
499
  }
487
- if (meta && packageJsonPath && args.length === 0) {
488
- if (!isSet(meta.runNpmInstallSet)) {
489
- meta.runNpmInstallSet = /* @__PURE__ */ new Set();
490
- }
491
- if (isSet(meta.runNpmInstallSet)) {
492
- if (meta.runNpmInstallSet.has(packageJsonPath)) {
493
- return false;
494
- } else {
495
- meta.runNpmInstallSet.add(packageJsonPath);
496
- }
500
+ const defaultInstall = args.length === 0;
501
+ if (meta && packageJsonPath && defaultInstall) {
502
+ const { alreadyInstalled, runNpmInstallSet } = checkIfAlreadyInstalled(
503
+ meta.runNpmInstallSet,
504
+ packageJsonPath
505
+ );
506
+ if (alreadyInstalled) {
507
+ return false;
497
508
  }
509
+ meta.runNpmInstallSet = runNpmInstallSet;
498
510
  }
499
511
  const installTime = Date.now();
500
512
  console.log("Installing dependencies...");
@@ -509,7 +521,8 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
509
521
  nodeVersion,
510
522
  env,
511
523
  packageJsonEngines: packageJson?.engines,
512
- turboSupportsCorepackHome
524
+ turboSupportsCorepackHome,
525
+ projectCreatedAt
513
526
  });
514
527
  await runInstallCommand({
515
528
  packageManager: cliType,
@@ -529,7 +542,8 @@ function getEnvForPackageManager({
529
542
  nodeVersion,
530
543
  env,
531
544
  packageJsonEngines,
532
- turboSupportsCorepackHome
545
+ turboSupportsCorepackHome,
546
+ projectCreatedAt
533
547
  }) {
534
548
  const corepackEnabled = usingCorepack(
535
549
  env,
@@ -546,7 +560,8 @@ function getEnvForPackageManager({
546
560
  corepackPackageManager: packageJsonPackageManager,
547
561
  nodeVersion,
548
562
  corepackEnabled,
549
- packageJsonEngines
563
+ packageJsonEngines,
564
+ projectCreatedAt
550
565
  });
551
566
  if (corepackEnabled) {
552
567
  (0, import_debug.default)(
@@ -568,10 +583,26 @@ function getEnvForPackageManager({
568
583
  const oldPath = env.PATH + "";
569
584
  newEnv.PATH = `${newPath}${import_path.default.delimiter}${oldPath}`;
570
585
  if (detectedLockfile && detectedPackageManager) {
571
- const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
572
- console.log(
573
- `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager}`
574
- );
586
+ const detectedV9PnpmLockfile = detectedLockfile === "pnpm-lock.yaml" && lockfileVersion === 9;
587
+ const pnpm10UsingPackageJsonPackageManager = detectedPackageManager === "pnpm@10.x" && packageJsonPackageManager;
588
+ if (pnpm10UsingPackageJsonPackageManager) {
589
+ const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
590
+ console.log(
591
+ `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager} with package.json#packageManager ${packageJsonPackageManager}`
592
+ );
593
+ } else if (detectedV9PnpmLockfile) {
594
+ const otherVersion = detectedPackageManager === "pnpm@10.x" ? `pnpm@9.x` : `pnpm@10.x`;
595
+ console.log(
596
+ `Detected \`${detectedLockfile}\` ${lockfileVersion} which may be generated by pnpm@9.x or pnpm@10.x
597
+ Using ${detectedPackageManager} based on project creation date
598
+ To use ${otherVersion}, manually opt in using corepack (https://vercel.com/docs/deployments/configure-a-build#corepack)`
599
+ );
600
+ } else {
601
+ const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
602
+ console.log(
603
+ `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager}`
604
+ );
605
+ }
575
606
  if (cliType === "bun") {
576
607
  console.warn(
577
608
  "Warning: Bun is used as a package manager at build time only, not at runtime with Functions"
@@ -584,7 +615,8 @@ function getEnvForPackageManager({
584
615
  }
585
616
  return newEnv;
586
617
  }
587
- function detectPnpmVersion(lockfileVersion) {
618
+ const PNPM_10_PREFERRED_AT = /* @__PURE__ */ new Date("2025-02-27T20:00:00Z");
619
+ function detectPnpmVersion(lockfileVersion, projectCreatedAt) {
588
620
  switch (true) {
589
621
  case lockfileVersion === void 0:
590
622
  return "not found";
@@ -594,8 +626,12 @@ function detectPnpmVersion(lockfileVersion) {
594
626
  return "pnpm 7";
595
627
  case (lockfileVersion === 6 || lockfileVersion === 6.1):
596
628
  return "pnpm 8";
597
- case (lockfileVersion === 7 || lockfileVersion === 9):
629
+ case lockfileVersion === 7:
598
630
  return "pnpm 9";
631
+ case lockfileVersion === 9: {
632
+ const projectPrefersPnpm10 = projectCreatedAt && projectCreatedAt >= PNPM_10_PREFERRED_AT.getTime();
633
+ return projectPrefersPnpm10 ? "pnpm 10" : "pnpm 9";
634
+ }
599
635
  default:
600
636
  return "not found";
601
637
  }
@@ -609,6 +645,8 @@ function validLockfileForPackageManager(cliType, lockfileVersion, packageManager
609
645
  return true;
610
646
  case "pnpm":
611
647
  switch (packageManagerMajorVersion) {
648
+ case 10:
649
+ return lockfileVersion === 9;
612
650
  case 9:
613
651
  if ("9.0.0" === packageManagerVersion.version && lockfileVersion === 6) {
614
652
  return false;
@@ -630,25 +668,34 @@ function getPathOverrideForPackageManager({
630
668
  lockfileVersion,
631
669
  corepackPackageManager,
632
670
  corepackEnabled = true,
633
- packageJsonEngines
671
+ packageJsonEngines,
672
+ projectCreatedAt
634
673
  }) {
635
- const detectedPackageManger = detectPackageManager(cliType, lockfileVersion);
636
- if (!corepackPackageManager || !corepackEnabled) {
637
- if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
674
+ const detectedPackageManger = detectPackageManager(
675
+ cliType,
676
+ lockfileVersion,
677
+ projectCreatedAt
678
+ );
679
+ const usingCorepack2 = corepackPackageManager && corepackEnabled;
680
+ if (usingCorepack2) {
681
+ validateCorepackPackageManager(
682
+ cliType,
683
+ lockfileVersion,
684
+ corepackPackageManager,
685
+ packageJsonEngines?.pnpm
686
+ );
687
+ return NO_OVERRIDE;
688
+ }
689
+ if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
690
+ const usingDetected = detectedPackageManger?.pnpmVersionRange !== "10.x" || !corepackPackageManager;
691
+ if (usingDetected) {
638
692
  checkEnginesPnpmAgainstDetected(
639
693
  packageJsonEngines.pnpm,
640
694
  detectedPackageManger
641
695
  );
642
696
  }
643
- return detectedPackageManger ?? NO_OVERRIDE;
644
697
  }
645
- validateCorepackPackageManager(
646
- cliType,
647
- lockfileVersion,
648
- corepackPackageManager,
649
- packageJsonEngines?.pnpm
650
- );
651
- return NO_OVERRIDE;
698
+ return detectedPackageManger ?? NO_OVERRIDE;
652
699
  }
653
700
  function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
654
701
  if (detectedPackageManger?.pnpmVersionRange && (0, import_semver.validRange)(detectedPackageManger.pnpmVersionRange) && (0, import_semver.validRange)(enginesPnpm)) {
@@ -723,12 +770,12 @@ function validateVersionSpecifier(version) {
723
770
  packageVersion
724
771
  };
725
772
  }
726
- function detectPackageManager(cliType, lockfileVersion) {
773
+ function detectPackageManager(cliType, lockfileVersion, projectCreatedAt) {
727
774
  switch (cliType) {
728
775
  case "npm":
729
776
  return void 0;
730
777
  case "pnpm":
731
- switch (detectPnpmVersion(lockfileVersion)) {
778
+ switch (detectPnpmVersion(lockfileVersion, projectCreatedAt)) {
732
779
  case "pnpm 7":
733
780
  return {
734
781
  path: "/pnpm7/node_modules/.bin",
@@ -750,6 +797,13 @@ function detectPackageManager(cliType, lockfileVersion) {
750
797
  detectedPackageManager: "pnpm@9.x",
751
798
  pnpmVersionRange: "9.x"
752
799
  };
800
+ case "pnpm 10":
801
+ return {
802
+ path: "/pnpm10/node_modules/.bin",
803
+ detectedLockfile: "pnpm-lock.yaml",
804
+ detectedPackageManager: "pnpm@10.x",
805
+ pnpmVersionRange: "10.x"
806
+ };
753
807
  case "pnpm 6":
754
808
  return {
755
809
  // undefined because pnpm@6 is the current default in the build container
@@ -813,7 +867,8 @@ async function runCustomInstallCommand({
813
867
  destPath,
814
868
  installCommand,
815
869
  nodeVersion,
816
- spawnOpts
870
+ spawnOpts,
871
+ projectCreatedAt
817
872
  }) {
818
873
  console.log(`Running "install" command: \`${installCommand}\`...`);
819
874
  const {
@@ -830,7 +885,8 @@ async function runCustomInstallCommand({
830
885
  nodeVersion,
831
886
  env: spawnOpts?.env || {},
832
887
  packageJsonEngines: packageJson?.engines,
833
- turboSupportsCorepackHome
888
+ turboSupportsCorepackHome,
889
+ projectCreatedAt
834
890
  });
835
891
  (0, import_debug.default)(`Running with $PATH:`, env?.PATH || "");
836
892
  await execCommand(installCommand, {
@@ -839,7 +895,7 @@ async function runCustomInstallCommand({
839
895
  cwd: destPath
840
896
  });
841
897
  }
842
- async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
898
+ async function runPackageJsonScript(destPath, scriptNames, spawnOpts, projectCreatedAt) {
843
899
  (0, import_assert.default)(import_path.default.isAbsolute(destPath));
844
900
  const {
845
901
  packageJson,
@@ -866,7 +922,8 @@ async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
866
922
  nodeVersion: void 0,
867
923
  env: (0, import_clone_env.cloneEnv)(process.env, spawnOpts?.env),
868
924
  packageJsonEngines: packageJson?.engines,
869
- turboSupportsCorepackHome
925
+ turboSupportsCorepackHome,
926
+ projectCreatedAt
870
927
  })
871
928
  };
872
929
  if (cliType === "npm") {
@@ -921,6 +978,7 @@ const installDependencies = (0, import_util.deprecate)(
921
978
  );
922
979
  // Annotate the CommonJS export names for ESM import in node:
923
980
  0 && (module.exports = {
981
+ PNPM_10_PREFERRED_AT,
924
982
  detectPackageManager,
925
983
  execCommand,
926
984
  getEnvForPackageManager,
package/dist/index.js CHANGED
@@ -23474,8 +23474,20 @@ async function runInstallCommand({
23474
23474
  }
23475
23475
  await spawnAsync(packageManager, commandArguments, opts);
23476
23476
  }
23477
+ function initializeSet(set) {
23478
+ if (!isSet(set)) {
23479
+ return /* @__PURE__ */ new Set();
23480
+ }
23481
+ return set;
23482
+ }
23483
+ function checkIfAlreadyInstalled(runNpmInstallSet, packageJsonPath) {
23484
+ const initializedRunNpmInstallSet = initializeSet(runNpmInstallSet);
23485
+ const alreadyInstalled = initializedRunNpmInstallSet.has(packageJsonPath);
23486
+ initializedRunNpmInstallSet.add(packageJsonPath);
23487
+ return { alreadyInstalled, runNpmInstallSet: initializedRunNpmInstallSet };
23488
+ }
23477
23489
  var runNpmInstallSema = new import_async_sema4.default(1);
23478
- async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion) {
23490
+ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion, projectCreatedAt) {
23479
23491
  if (meta?.isDev) {
23480
23492
  debug("Skipping dependency installation because dev mode is enabled");
23481
23493
  return false;
@@ -23497,17 +23509,16 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
23497
23509
  );
23498
23510
  return false;
23499
23511
  }
23500
- if (meta && packageJsonPath && args.length === 0) {
23501
- if (!isSet(meta.runNpmInstallSet)) {
23502
- meta.runNpmInstallSet = /* @__PURE__ */ new Set();
23503
- }
23504
- if (isSet(meta.runNpmInstallSet)) {
23505
- if (meta.runNpmInstallSet.has(packageJsonPath)) {
23506
- return false;
23507
- } else {
23508
- meta.runNpmInstallSet.add(packageJsonPath);
23509
- }
23512
+ const defaultInstall = args.length === 0;
23513
+ if (meta && packageJsonPath && defaultInstall) {
23514
+ const { alreadyInstalled, runNpmInstallSet } = checkIfAlreadyInstalled(
23515
+ meta.runNpmInstallSet,
23516
+ packageJsonPath
23517
+ );
23518
+ if (alreadyInstalled) {
23519
+ return false;
23510
23520
  }
23521
+ meta.runNpmInstallSet = runNpmInstallSet;
23511
23522
  }
23512
23523
  const installTime = Date.now();
23513
23524
  console.log("Installing dependencies...");
@@ -23522,7 +23533,8 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
23522
23533
  nodeVersion,
23523
23534
  env,
23524
23535
  packageJsonEngines: packageJson?.engines,
23525
- turboSupportsCorepackHome
23536
+ turboSupportsCorepackHome,
23537
+ projectCreatedAt
23526
23538
  });
23527
23539
  await runInstallCommand({
23528
23540
  packageManager: cliType,
@@ -23542,7 +23554,8 @@ function getEnvForPackageManager({
23542
23554
  nodeVersion,
23543
23555
  env,
23544
23556
  packageJsonEngines,
23545
- turboSupportsCorepackHome
23557
+ turboSupportsCorepackHome,
23558
+ projectCreatedAt
23546
23559
  }) {
23547
23560
  const corepackEnabled = usingCorepack(
23548
23561
  env,
@@ -23559,7 +23572,8 @@ function getEnvForPackageManager({
23559
23572
  corepackPackageManager: packageJsonPackageManager,
23560
23573
  nodeVersion,
23561
23574
  corepackEnabled,
23562
- packageJsonEngines
23575
+ packageJsonEngines,
23576
+ projectCreatedAt
23563
23577
  });
23564
23578
  if (corepackEnabled) {
23565
23579
  debug(
@@ -23581,10 +23595,26 @@ function getEnvForPackageManager({
23581
23595
  const oldPath = env.PATH + "";
23582
23596
  newEnv.PATH = `${newPath}${import_path5.default.delimiter}${oldPath}`;
23583
23597
  if (detectedLockfile && detectedPackageManager) {
23584
- const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
23585
- console.log(
23586
- `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager}`
23587
- );
23598
+ const detectedV9PnpmLockfile = detectedLockfile === "pnpm-lock.yaml" && lockfileVersion === 9;
23599
+ const pnpm10UsingPackageJsonPackageManager = detectedPackageManager === "pnpm@10.x" && packageJsonPackageManager;
23600
+ if (pnpm10UsingPackageJsonPackageManager) {
23601
+ const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
23602
+ console.log(
23603
+ `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager} with package.json#packageManager ${packageJsonPackageManager}`
23604
+ );
23605
+ } else if (detectedV9PnpmLockfile) {
23606
+ const otherVersion = detectedPackageManager === "pnpm@10.x" ? `pnpm@9.x` : `pnpm@10.x`;
23607
+ console.log(
23608
+ `Detected \`${detectedLockfile}\` ${lockfileVersion} which may be generated by pnpm@9.x or pnpm@10.x
23609
+ Using ${detectedPackageManager} based on project creation date
23610
+ To use ${otherVersion}, manually opt in using corepack (https://vercel.com/docs/deployments/configure-a-build#corepack)`
23611
+ );
23612
+ } else {
23613
+ const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
23614
+ console.log(
23615
+ `Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager}`
23616
+ );
23617
+ }
23588
23618
  if (cliType === "bun") {
23589
23619
  console.warn(
23590
23620
  "Warning: Bun is used as a package manager at build time only, not at runtime with Functions"
@@ -23597,7 +23627,8 @@ function getEnvForPackageManager({
23597
23627
  }
23598
23628
  return newEnv;
23599
23629
  }
23600
- function detectPnpmVersion(lockfileVersion) {
23630
+ var PNPM_10_PREFERRED_AT = /* @__PURE__ */ new Date("2025-02-27T20:00:00Z");
23631
+ function detectPnpmVersion(lockfileVersion, projectCreatedAt) {
23601
23632
  switch (true) {
23602
23633
  case lockfileVersion === void 0:
23603
23634
  return "not found";
@@ -23607,8 +23638,12 @@ function detectPnpmVersion(lockfileVersion) {
23607
23638
  return "pnpm 7";
23608
23639
  case (lockfileVersion === 6 || lockfileVersion === 6.1):
23609
23640
  return "pnpm 8";
23610
- case (lockfileVersion === 7 || lockfileVersion === 9):
23641
+ case lockfileVersion === 7:
23611
23642
  return "pnpm 9";
23643
+ case lockfileVersion === 9: {
23644
+ const projectPrefersPnpm10 = projectCreatedAt && projectCreatedAt >= PNPM_10_PREFERRED_AT.getTime();
23645
+ return projectPrefersPnpm10 ? "pnpm 10" : "pnpm 9";
23646
+ }
23612
23647
  default:
23613
23648
  return "not found";
23614
23649
  }
@@ -23622,6 +23657,8 @@ function validLockfileForPackageManager(cliType, lockfileVersion, packageManager
23622
23657
  return true;
23623
23658
  case "pnpm":
23624
23659
  switch (packageManagerMajorVersion) {
23660
+ case 10:
23661
+ return lockfileVersion === 9;
23625
23662
  case 9:
23626
23663
  if ("9.0.0" === packageManagerVersion.version && lockfileVersion === 6) {
23627
23664
  return false;
@@ -23643,25 +23680,34 @@ function getPathOverrideForPackageManager({
23643
23680
  lockfileVersion,
23644
23681
  corepackPackageManager,
23645
23682
  corepackEnabled = true,
23646
- packageJsonEngines
23683
+ packageJsonEngines,
23684
+ projectCreatedAt
23647
23685
  }) {
23648
- const detectedPackageManger = detectPackageManager(cliType, lockfileVersion);
23649
- if (!corepackPackageManager || !corepackEnabled) {
23650
- if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
23686
+ const detectedPackageManger = detectPackageManager(
23687
+ cliType,
23688
+ lockfileVersion,
23689
+ projectCreatedAt
23690
+ );
23691
+ const usingCorepack2 = corepackPackageManager && corepackEnabled;
23692
+ if (usingCorepack2) {
23693
+ validateCorepackPackageManager(
23694
+ cliType,
23695
+ lockfileVersion,
23696
+ corepackPackageManager,
23697
+ packageJsonEngines?.pnpm
23698
+ );
23699
+ return NO_OVERRIDE;
23700
+ }
23701
+ if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
23702
+ const usingDetected = detectedPackageManger?.pnpmVersionRange !== "10.x" || !corepackPackageManager;
23703
+ if (usingDetected) {
23651
23704
  checkEnginesPnpmAgainstDetected(
23652
23705
  packageJsonEngines.pnpm,
23653
23706
  detectedPackageManger
23654
23707
  );
23655
23708
  }
23656
- return detectedPackageManger ?? NO_OVERRIDE;
23657
23709
  }
23658
- validateCorepackPackageManager(
23659
- cliType,
23660
- lockfileVersion,
23661
- corepackPackageManager,
23662
- packageJsonEngines?.pnpm
23663
- );
23664
- return NO_OVERRIDE;
23710
+ return detectedPackageManger ?? NO_OVERRIDE;
23665
23711
  }
23666
23712
  function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
23667
23713
  if (detectedPackageManger?.pnpmVersionRange && (0, import_semver2.validRange)(detectedPackageManger.pnpmVersionRange) && (0, import_semver2.validRange)(enginesPnpm)) {
@@ -23736,12 +23782,12 @@ function validateVersionSpecifier(version) {
23736
23782
  packageVersion
23737
23783
  };
23738
23784
  }
23739
- function detectPackageManager(cliType, lockfileVersion) {
23785
+ function detectPackageManager(cliType, lockfileVersion, projectCreatedAt) {
23740
23786
  switch (cliType) {
23741
23787
  case "npm":
23742
23788
  return void 0;
23743
23789
  case "pnpm":
23744
- switch (detectPnpmVersion(lockfileVersion)) {
23790
+ switch (detectPnpmVersion(lockfileVersion, projectCreatedAt)) {
23745
23791
  case "pnpm 7":
23746
23792
  return {
23747
23793
  path: "/pnpm7/node_modules/.bin",
@@ -23763,6 +23809,13 @@ function detectPackageManager(cliType, lockfileVersion) {
23763
23809
  detectedPackageManager: "pnpm@9.x",
23764
23810
  pnpmVersionRange: "9.x"
23765
23811
  };
23812
+ case "pnpm 10":
23813
+ return {
23814
+ path: "/pnpm10/node_modules/.bin",
23815
+ detectedLockfile: "pnpm-lock.yaml",
23816
+ detectedPackageManager: "pnpm@10.x",
23817
+ pnpmVersionRange: "10.x"
23818
+ };
23766
23819
  case "pnpm 6":
23767
23820
  return {
23768
23821
  // undefined because pnpm@6 is the current default in the build container
@@ -23826,7 +23879,8 @@ async function runCustomInstallCommand({
23826
23879
  destPath,
23827
23880
  installCommand,
23828
23881
  nodeVersion,
23829
- spawnOpts
23882
+ spawnOpts,
23883
+ projectCreatedAt
23830
23884
  }) {
23831
23885
  console.log(`Running "install" command: \`${installCommand}\`...`);
23832
23886
  const {
@@ -23843,7 +23897,8 @@ async function runCustomInstallCommand({
23843
23897
  nodeVersion,
23844
23898
  env: spawnOpts?.env || {},
23845
23899
  packageJsonEngines: packageJson?.engines,
23846
- turboSupportsCorepackHome
23900
+ turboSupportsCorepackHome,
23901
+ projectCreatedAt
23847
23902
  });
23848
23903
  debug(`Running with $PATH:`, env?.PATH || "");
23849
23904
  await execCommand(installCommand, {
@@ -23852,7 +23907,7 @@ async function runCustomInstallCommand({
23852
23907
  cwd: destPath
23853
23908
  });
23854
23909
  }
23855
- async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
23910
+ async function runPackageJsonScript(destPath, scriptNames, spawnOpts, projectCreatedAt) {
23856
23911
  (0, import_assert6.default)(import_path5.default.isAbsolute(destPath));
23857
23912
  const {
23858
23913
  packageJson,
@@ -23879,7 +23934,8 @@ async function runPackageJsonScript(destPath, scriptNames, spawnOpts) {
23879
23934
  nodeVersion: void 0,
23880
23935
  env: cloneEnv(process.env, spawnOpts?.env),
23881
23936
  packageJsonEngines: packageJson?.engines,
23882
- turboSupportsCorepackHome
23937
+ turboSupportsCorepackHome,
23938
+ projectCreatedAt
23883
23939
  })
23884
23940
  };
23885
23941
  if (cliType === "npm") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "10.1.0",
3
+ "version": "10.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",