@vercel/build-utils 7.2.3 → 7.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 7.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Select Node.js version based on what's available in build-container ([#10822](https://github.com/vercel/vercel/pull/10822))
8
+
3
9
  ## 7.2.3
4
10
 
5
11
  ### Patch Changes
@@ -1,12 +1,103 @@
1
1
  import { NodeVersion } from '../types';
2
- export declare function getLatestNodeVersion(): {
2
+ export type NodeVersionMajor = ReturnType<typeof getOptions>[number]['major'];
3
+ declare function getOptions(): readonly [{
3
4
  readonly major: 18;
4
5
  readonly range: "18.x";
5
6
  readonly runtime: "nodejs18.x";
7
+ }, {
8
+ readonly major: 16;
9
+ readonly range: "16.x";
10
+ readonly runtime: "nodejs16.x";
11
+ readonly discontinueDate: Date;
12
+ }, {
13
+ readonly major: 14;
14
+ readonly range: "14.x";
15
+ readonly runtime: "nodejs14.x";
16
+ readonly discontinueDate: Date;
17
+ }, {
18
+ readonly major: 12;
19
+ readonly range: "12.x";
20
+ readonly runtime: "nodejs12.x";
21
+ readonly discontinueDate: Date;
22
+ }, {
23
+ readonly major: 10;
24
+ readonly range: "10.x";
25
+ readonly runtime: "nodejs10.x";
26
+ readonly discontinueDate: Date;
27
+ }, {
28
+ readonly major: 8;
29
+ readonly range: "8.10.x";
30
+ readonly runtime: "nodejs8.10";
31
+ readonly discontinueDate: Date;
32
+ }] | readonly [{
33
+ readonly major: 20;
34
+ readonly range: "20.x";
35
+ readonly runtime: "nodejs20.x";
36
+ }, {
37
+ readonly major: 18;
38
+ readonly range: "18.x";
39
+ readonly runtime: "nodejs18.x";
40
+ }, {
41
+ readonly major: 16;
42
+ readonly range: "16.x";
43
+ readonly runtime: "nodejs16.x";
44
+ readonly discontinueDate: Date;
45
+ }, {
46
+ readonly major: 14;
47
+ readonly range: "14.x";
48
+ readonly runtime: "nodejs14.x";
49
+ readonly discontinueDate: Date;
50
+ }, {
51
+ readonly major: 12;
52
+ readonly range: "12.x";
53
+ readonly runtime: "nodejs12.x";
54
+ readonly discontinueDate: Date;
55
+ }, {
56
+ readonly major: 10;
57
+ readonly range: "10.x";
58
+ readonly runtime: "nodejs10.x";
59
+ readonly discontinueDate: Date;
60
+ }, {
61
+ readonly major: 8;
62
+ readonly range: "8.10.x";
63
+ readonly runtime: "nodejs8.10";
64
+ readonly discontinueDate: Date;
65
+ }];
66
+ export declare function getAvailableNodeVersions(): NodeVersionMajor[];
67
+ export declare function getLatestNodeVersion(availableVersions?: NodeVersionMajor[]): {
68
+ readonly major: 18;
69
+ readonly range: "18.x";
70
+ readonly runtime: "nodejs18.x";
71
+ } | {
72
+ readonly major: 16;
73
+ readonly range: "16.x";
74
+ readonly runtime: "nodejs16.x";
75
+ readonly discontinueDate: Date;
76
+ } | {
77
+ readonly major: 14;
78
+ readonly range: "14.x";
79
+ readonly runtime: "nodejs14.x";
80
+ readonly discontinueDate: Date;
81
+ } | {
82
+ readonly major: 12;
83
+ readonly range: "12.x";
84
+ readonly runtime: "nodejs12.x";
85
+ readonly discontinueDate: Date;
86
+ } | {
87
+ readonly major: 10;
88
+ readonly range: "10.x";
89
+ readonly runtime: "nodejs10.x";
90
+ readonly discontinueDate: Date;
91
+ } | {
92
+ readonly major: 8;
93
+ readonly range: "8.10.x";
94
+ readonly runtime: "nodejs8.10";
95
+ readonly discontinueDate: Date;
6
96
  } | {
7
97
  readonly major: 20;
8
98
  readonly range: "20.x";
9
99
  readonly runtime: "nodejs20.x";
10
100
  };
11
101
  export declare function getDiscontinuedNodeVersions(): NodeVersion[];
12
- export declare function getSupportedNodeVersion(engineRange: string | undefined, isAuto?: boolean): Promise<NodeVersion>;
102
+ export declare function getSupportedNodeVersion(engineRange: string | undefined, isAuto?: boolean, availableVersions?: NodeVersionMajor[]): Promise<NodeVersion>;
103
+ export {};
@@ -28,11 +28,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var node_version_exports = {};
30
30
  __export(node_version_exports, {
31
+ getAvailableNodeVersions: () => getAvailableNodeVersions,
31
32
  getDiscontinuedNodeVersions: () => getDiscontinuedNodeVersions,
32
33
  getLatestNodeVersion: () => getLatestNodeVersion,
33
34
  getSupportedNodeVersion: () => getSupportedNodeVersion
34
35
  });
35
36
  module.exports = __toCommonJS(node_version_exports);
37
+ var import_fs = require("fs");
36
38
  var import_semver = require("semver");
37
39
  var import_errors = require("../errors");
38
40
  var import_debug = __toESM(require("../debug"));
@@ -78,22 +80,42 @@ function getOptions() {
78
80
  }
79
81
  return options;
80
82
  }
83
+ function isNodeVersionAvailable(version) {
84
+ try {
85
+ return (0, import_fs.statSync)(`/node${version.major}`).isDirectory();
86
+ } catch {
87
+ }
88
+ return false;
89
+ }
90
+ function getAvailableNodeVersions() {
91
+ return getOptions().filter(isNodeVersionAvailable).map((n) => n.major);
92
+ }
81
93
  function getHint(isAuto = false) {
82
94
  const { major, range } = getLatestNodeVersion();
83
95
  return isAuto ? `Please set Node.js Version to ${range} in your Project Settings to use Node.js ${major}.` : `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
84
96
  }
85
- function getLatestNodeVersion() {
86
- return getOptions()[0];
97
+ function getLatestNodeVersion(availableVersions) {
98
+ const all = getOptions();
99
+ if (availableVersions) {
100
+ for (const version of all) {
101
+ for (const major of availableVersions) {
102
+ if (version.major === major) {
103
+ return version;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ return all[0];
87
109
  }
88
110
  function getDiscontinuedNodeVersions() {
89
111
  return getOptions().filter(isDiscontinued);
90
112
  }
91
- async function getSupportedNodeVersion(engineRange, isAuto = false) {
92
- let selection = getLatestNodeVersion();
113
+ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVersions) {
114
+ let selection;
93
115
  if (engineRange) {
94
116
  const found = (0, import_semver.validRange)(engineRange) && getOptions().some((o) => {
95
117
  selection = o;
96
- return (0, import_semver.intersects)(o.range, engineRange);
118
+ return (0, import_semver.intersects)(o.range, engineRange) && (availableVersions?.length ? availableVersions.includes(o.major) : true);
97
119
  });
98
120
  if (!found) {
99
121
  throw new import_errors.NowBuildError({
@@ -105,6 +127,9 @@ async function getSupportedNodeVersion(engineRange, isAuto = false) {
105
127
  });
106
128
  }
107
129
  }
130
+ if (!selection) {
131
+ selection = getLatestNodeVersion(availableVersions);
132
+ }
108
133
  if (isDiscontinued(selection)) {
109
134
  const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
110
135
  throw new import_errors.NowBuildError({
@@ -130,6 +155,7 @@ function isDiscontinued({ discontinueDate }) {
130
155
  }
131
156
  // Annotate the CommonJS export names for ESM import in node:
132
157
  0 && (module.exports = {
158
+ getAvailableNodeVersions,
133
159
  getDiscontinuedNodeVersions,
134
160
  getLatestNodeVersion,
135
161
  getSupportedNodeVersion
@@ -74,7 +74,7 @@ export declare function getNodeBinPath({ cwd, }: {
74
74
  export declare function getNodeBinPaths({ start, base, }: TraverseUpDirectoriesProps): string[];
75
75
  export declare function runShellScript(fsPath: string, args?: string[], spawnOpts?: SpawnOptions): Promise<boolean>;
76
76
  export declare function getSpawnOptions(meta: Meta, nodeVersion: NodeVersion): SpawnOptions;
77
- export declare function getNodeVersion(destPath: string, nodeVersionFallback?: string | undefined, config?: Config, meta?: Meta): Promise<NodeVersion>;
77
+ export declare function getNodeVersion(destPath: string, nodeVersionFallback?: string | undefined, config?: Config, meta?: Meta, availableVersions?: (20 | 10 | 16 | 18 | 14 | 12 | 8)[]): Promise<NodeVersion>;
78
78
  export declare function scanParentDirs(destPath: string, readPackageJson?: boolean): Promise<ScanParentDirsResult>;
79
79
  export declare function walkParentDirs({ base, start, filename, }: WalkParentDirsProps): Promise<string | null>;
80
80
  export declare function runNpmInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta, nodeVersion?: NodeVersion): Promise<boolean>;
@@ -171,8 +171,8 @@ function getSpawnOptions(meta, nodeVersion) {
171
171
  }
172
172
  return opts;
173
173
  }
174
- async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}) {
175
- const latest = (0, import_node_version.getLatestNodeVersion)();
174
+ async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}, availableVersions = (0, import_node_version.getAvailableNodeVersions)()) {
175
+ const latest = (0, import_node_version.getLatestNodeVersion)(availableVersions);
176
176
  if (meta.isDev) {
177
177
  return { ...latest, runtime: "nodejs" };
178
178
  }
@@ -197,7 +197,7 @@ async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL
197
197
  nodeVersion = node;
198
198
  isAuto = false;
199
199
  }
200
- return (0, import_node_version.getSupportedNodeVersion)(nodeVersion, isAuto);
200
+ return (0, import_node_version.getSupportedNodeVersion)(nodeVersion, isAuto, availableVersions);
201
201
  }
202
202
  async function scanParentDirs(destPath, readPackageJson = false) {
203
203
  (0, import_assert.default)(import_path.default.isAbsolute(destPath));
package/dist/index.js CHANGED
@@ -3548,8 +3548,8 @@ var require_copy_sync = __commonJS({
3548
3548
  return getStats(destStat, src, dest, opts);
3549
3549
  }
3550
3550
  function getStats(destStat, src, dest, opts) {
3551
- const statSync = opts.dereference ? fs5.statSync : fs5.lstatSync;
3552
- const srcStat = statSync(src);
3551
+ const statSync2 = opts.dereference ? fs5.statSync : fs5.lstatSync;
3552
+ const srcStat = statSync2(src);
3553
3553
  if (srcStat.isDirectory())
3554
3554
  return onDir(srcStat, destStat, src, dest, opts);
3555
3555
  else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice())
@@ -21589,6 +21589,7 @@ var import_semver2 = __toESM(require_semver2());
21589
21589
  var import_util2 = require("util");
21590
21590
 
21591
21591
  // src/fs/node-version.ts
21592
+ var import_fs = require("fs");
21592
21593
  var import_semver = __toESM(require_semver2());
21593
21594
  function getOptions() {
21594
21595
  const options = [
@@ -21632,22 +21633,42 @@ function getOptions() {
21632
21633
  }
21633
21634
  return options;
21634
21635
  }
21636
+ function isNodeVersionAvailable(version) {
21637
+ try {
21638
+ return (0, import_fs.statSync)(`/node${version.major}`).isDirectory();
21639
+ } catch {
21640
+ }
21641
+ return false;
21642
+ }
21643
+ function getAvailableNodeVersions() {
21644
+ return getOptions().filter(isNodeVersionAvailable).map((n) => n.major);
21645
+ }
21635
21646
  function getHint(isAuto = false) {
21636
21647
  const { major, range } = getLatestNodeVersion();
21637
21648
  return isAuto ? `Please set Node.js Version to ${range} in your Project Settings to use Node.js ${major}.` : `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
21638
21649
  }
21639
- function getLatestNodeVersion() {
21640
- return getOptions()[0];
21650
+ function getLatestNodeVersion(availableVersions) {
21651
+ const all = getOptions();
21652
+ if (availableVersions) {
21653
+ for (const version of all) {
21654
+ for (const major of availableVersions) {
21655
+ if (version.major === major) {
21656
+ return version;
21657
+ }
21658
+ }
21659
+ }
21660
+ }
21661
+ return all[0];
21641
21662
  }
21642
21663
  function getDiscontinuedNodeVersions() {
21643
21664
  return getOptions().filter(isDiscontinued);
21644
21665
  }
21645
- async function getSupportedNodeVersion(engineRange, isAuto = false) {
21646
- let selection = getLatestNodeVersion();
21666
+ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVersions) {
21667
+ let selection;
21647
21668
  if (engineRange) {
21648
21669
  const found = (0, import_semver.validRange)(engineRange) && getOptions().some((o) => {
21649
21670
  selection = o;
21650
- return (0, import_semver.intersects)(o.range, engineRange);
21671
+ return (0, import_semver.intersects)(o.range, engineRange) && (availableVersions?.length ? availableVersions.includes(o.major) : true);
21651
21672
  });
21652
21673
  if (!found) {
21653
21674
  throw new NowBuildError({
@@ -21659,6 +21680,9 @@ async function getSupportedNodeVersion(engineRange, isAuto = false) {
21659
21680
  });
21660
21681
  }
21661
21682
  }
21683
+ if (!selection) {
21684
+ selection = getLatestNodeVersion(availableVersions);
21685
+ }
21662
21686
  if (isDiscontinued(selection)) {
21663
21687
  const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
21664
21688
  throw new NowBuildError({
@@ -21853,8 +21877,8 @@ function getSpawnOptions(meta, nodeVersion) {
21853
21877
  }
21854
21878
  return opts;
21855
21879
  }
21856
- async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}) {
21857
- const latest = getLatestNodeVersion();
21880
+ async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}, availableVersions = getAvailableNodeVersions()) {
21881
+ const latest = getLatestNodeVersion(availableVersions);
21858
21882
  if (meta.isDev) {
21859
21883
  return { ...latest, runtime: "nodejs" };
21860
21884
  }
@@ -21879,7 +21903,7 @@ async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL
21879
21903
  nodeVersion = node;
21880
21904
  isAuto = false;
21881
21905
  }
21882
- return getSupportedNodeVersion(nodeVersion, isAuto);
21906
+ return getSupportedNodeVersion(nodeVersion, isAuto, availableVersions);
21883
21907
  }
21884
21908
  async function scanParentDirs(destPath, readPackageJson = false) {
21885
21909
  (0, import_assert6.default)(import_path5.default.isAbsolute(destPath));
@@ -22279,23 +22303,23 @@ function getPrefixedEnvVars({
22279
22303
 
22280
22304
  // src/hard-link-dir.ts
22281
22305
  var import_path7 = __toESM(require("path"));
22282
- var import_fs = require("fs");
22306
+ var import_fs2 = require("fs");
22283
22307
  async function hardLinkDir(src, destDirs) {
22284
22308
  if (destDirs.length === 0)
22285
22309
  return;
22286
22310
  destDirs = destDirs.filter((destDir) => import_path7.default.relative(destDir, src) !== "");
22287
- const files = await import_fs.promises.readdir(src);
22311
+ const files = await import_fs2.promises.readdir(src);
22288
22312
  await Promise.all(
22289
22313
  files.map(async (file) => {
22290
22314
  if (file === "node_modules")
22291
22315
  return;
22292
22316
  const srcFile = import_path7.default.join(src, file);
22293
- if ((await import_fs.promises.lstat(srcFile)).isDirectory()) {
22317
+ if ((await import_fs2.promises.lstat(srcFile)).isDirectory()) {
22294
22318
  const destSubdirs = await Promise.all(
22295
22319
  destDirs.map(async (destDir) => {
22296
22320
  const destSubdir = import_path7.default.join(destDir, file);
22297
22321
  try {
22298
- await import_fs.promises.mkdir(destSubdir, { recursive: true });
22322
+ await import_fs2.promises.mkdir(destSubdir, { recursive: true });
22299
22323
  } catch (err) {
22300
22324
  if (err.code !== "EEXIST")
22301
22325
  throw err;
@@ -22327,7 +22351,7 @@ async function linkOrCopyFile(srcFile, destFile) {
22327
22351
  await linkOrCopy(srcFile, destFile);
22328
22352
  } catch (err) {
22329
22353
  if (err.code === "ENOENT") {
22330
- await import_fs.promises.mkdir(import_path7.default.dirname(destFile), { recursive: true });
22354
+ await import_fs2.promises.mkdir(import_path7.default.dirname(destFile), { recursive: true });
22331
22355
  await linkOrCopy(srcFile, destFile);
22332
22356
  return;
22333
22357
  }
@@ -22338,11 +22362,11 @@ async function linkOrCopyFile(srcFile, destFile) {
22338
22362
  }
22339
22363
  async function linkOrCopy(srcFile, destFile) {
22340
22364
  try {
22341
- await import_fs.promises.link(srcFile, destFile);
22365
+ await import_fs2.promises.link(srcFile, destFile);
22342
22366
  } catch (err) {
22343
22367
  if (err.code !== "EXDEV")
22344
22368
  throw err;
22345
- await import_fs.promises.copyFile(srcFile, destFile);
22369
+ await import_fs2.promises.copyFile(srcFile, destFile);
22346
22370
  }
22347
22371
  }
22348
22372
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "7.2.3",
3
+ "version": "7.2.4",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",