@vercel/build-utils 7.2.2 → 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,17 @@
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
+
9
+ ## 7.2.3
10
+
11
+ ### Patch Changes
12
+
13
+ - Add experimental flag to allow Node.js v20 ([#10802](https://github.com/vercel/vercel/pull/10802))
14
+
3
15
  ## 7.2.2
4
16
 
5
17
  ### Patch Changes
@@ -1,8 +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;
96
+ } | {
97
+ readonly major: 20;
98
+ readonly range: "20.x";
99
+ readonly runtime: "nodejs20.x";
6
100
  };
7
101
  export declare function getDiscontinuedNodeVersions(): NodeVersion[];
8
- 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"));
@@ -70,24 +72,50 @@ function getOptions() {
70
72
  discontinueDate: /* @__PURE__ */ new Date("2020-01-06")
71
73
  }
72
74
  ];
75
+ if (process.env.VERCEL_ALLOW_NODEJS20 === "1") {
76
+ return [
77
+ { major: 20, range: "20.x", runtime: "nodejs20.x" },
78
+ ...options
79
+ ];
80
+ }
73
81
  return options;
74
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
+ }
75
93
  function getHint(isAuto = false) {
76
94
  const { major, range } = getLatestNodeVersion();
77
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}.`;
78
96
  }
79
- function getLatestNodeVersion() {
80
- 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];
81
109
  }
82
110
  function getDiscontinuedNodeVersions() {
83
111
  return getOptions().filter(isDiscontinued);
84
112
  }
85
- async function getSupportedNodeVersion(engineRange, isAuto = false) {
86
- let selection = getLatestNodeVersion();
113
+ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVersions) {
114
+ let selection;
87
115
  if (engineRange) {
88
116
  const found = (0, import_semver.validRange)(engineRange) && getOptions().some((o) => {
89
117
  selection = o;
90
- return (0, import_semver.intersects)(o.range, engineRange);
118
+ return (0, import_semver.intersects)(o.range, engineRange) && (availableVersions?.length ? availableVersions.includes(o.major) : true);
91
119
  });
92
120
  if (!found) {
93
121
  throw new import_errors.NowBuildError({
@@ -99,6 +127,9 @@ async function getSupportedNodeVersion(engineRange, isAuto = false) {
99
127
  });
100
128
  }
101
129
  }
130
+ if (!selection) {
131
+ selection = getLatestNodeVersion(availableVersions);
132
+ }
102
133
  if (isDiscontinued(selection)) {
103
134
  const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
104
135
  throw new import_errors.NowBuildError({
@@ -124,6 +155,7 @@ function isDiscontinued({ discontinueDate }) {
124
155
  }
125
156
  // Annotate the CommonJS export names for ESM import in node:
126
157
  0 && (module.exports = {
158
+ getAvailableNodeVersions,
127
159
  getDiscontinuedNodeVersions,
128
160
  getLatestNodeVersion,
129
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())
@@ -20349,9 +20349,11 @@ var require_toml = __commonJS({
20349
20349
  var require_dist = __commonJS({
20350
20350
  "../error-utils/dist/index.js"(exports2, module2) {
20351
20351
  "use strict";
20352
+ var __create2 = Object.create;
20352
20353
  var __defProp2 = Object.defineProperty;
20353
20354
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
20354
20355
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
20356
+ var __getProtoOf2 = Object.getPrototypeOf;
20355
20357
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
20356
20358
  var __export2 = (target, all) => {
20357
20359
  for (var name in all)
@@ -20365,6 +20367,14 @@ var require_dist = __commonJS({
20365
20367
  }
20366
20368
  return to;
20367
20369
  };
20370
+ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
20371
+ // If the importer is in node compatibility mode or this is not an ESM
20372
+ // file that has been converted to a CommonJS file using a Babel-
20373
+ // compatible transform (i.e. "__esModule" has not been set), then set
20374
+ // "default" to the CommonJS "module.exports" for node compatibility.
20375
+ isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
20376
+ mod
20377
+ ));
20368
20378
  var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
20369
20379
  var src_exports2 = {};
20370
20380
  __export2(src_exports2, {
@@ -20377,18 +20387,10 @@ var require_dist = __commonJS({
20377
20387
  normalizeError: () => normalizeError
20378
20388
  });
20379
20389
  module2.exports = __toCommonJS2(src_exports2);
20390
+ var import_node_util = __toESM2(require("util"));
20380
20391
  var isObject = (obj) => typeof obj === "object" && obj !== null;
20381
20392
  var isError = (error) => {
20382
- if (!isObject(error))
20383
- return false;
20384
- if (error instanceof Error)
20385
- return true;
20386
- while (error) {
20387
- if (Object.prototype.toString.call(error) === "[object Error]")
20388
- return true;
20389
- error = Object.getPrototypeOf(error);
20390
- }
20391
- return false;
20393
+ return import_node_util.default.types.isNativeError(error);
20392
20394
  };
20393
20395
  var isErrnoException2 = (error) => {
20394
20396
  return isError(error) && "code" in error;
@@ -21587,6 +21589,7 @@ var import_semver2 = __toESM(require_semver2());
21587
21589
  var import_util2 = require("util");
21588
21590
 
21589
21591
  // src/fs/node-version.ts
21592
+ var import_fs = require("fs");
21590
21593
  var import_semver = __toESM(require_semver2());
21591
21594
  function getOptions() {
21592
21595
  const options = [
@@ -21622,24 +21625,50 @@ function getOptions() {
21622
21625
  discontinueDate: /* @__PURE__ */ new Date("2020-01-06")
21623
21626
  }
21624
21627
  ];
21628
+ if (process.env.VERCEL_ALLOW_NODEJS20 === "1") {
21629
+ return [
21630
+ { major: 20, range: "20.x", runtime: "nodejs20.x" },
21631
+ ...options
21632
+ ];
21633
+ }
21625
21634
  return options;
21626
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
+ }
21627
21646
  function getHint(isAuto = false) {
21628
21647
  const { major, range } = getLatestNodeVersion();
21629
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}.`;
21630
21649
  }
21631
- function getLatestNodeVersion() {
21632
- 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];
21633
21662
  }
21634
21663
  function getDiscontinuedNodeVersions() {
21635
21664
  return getOptions().filter(isDiscontinued);
21636
21665
  }
21637
- async function getSupportedNodeVersion(engineRange, isAuto = false) {
21638
- let selection = getLatestNodeVersion();
21666
+ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVersions) {
21667
+ let selection;
21639
21668
  if (engineRange) {
21640
21669
  const found = (0, import_semver.validRange)(engineRange) && getOptions().some((o) => {
21641
21670
  selection = o;
21642
- return (0, import_semver.intersects)(o.range, engineRange);
21671
+ return (0, import_semver.intersects)(o.range, engineRange) && (availableVersions?.length ? availableVersions.includes(o.major) : true);
21643
21672
  });
21644
21673
  if (!found) {
21645
21674
  throw new NowBuildError({
@@ -21651,6 +21680,9 @@ async function getSupportedNodeVersion(engineRange, isAuto = false) {
21651
21680
  });
21652
21681
  }
21653
21682
  }
21683
+ if (!selection) {
21684
+ selection = getLatestNodeVersion(availableVersions);
21685
+ }
21654
21686
  if (isDiscontinued(selection)) {
21655
21687
  const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
21656
21688
  throw new NowBuildError({
@@ -21845,8 +21877,8 @@ function getSpawnOptions(meta, nodeVersion) {
21845
21877
  }
21846
21878
  return opts;
21847
21879
  }
21848
- async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}) {
21849
- 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);
21850
21882
  if (meta.isDev) {
21851
21883
  return { ...latest, runtime: "nodejs" };
21852
21884
  }
@@ -21871,7 +21903,7 @@ async function getNodeVersion(destPath, nodeVersionFallback = process.env.VERCEL
21871
21903
  nodeVersion = node;
21872
21904
  isAuto = false;
21873
21905
  }
21874
- return getSupportedNodeVersion(nodeVersion, isAuto);
21906
+ return getSupportedNodeVersion(nodeVersion, isAuto, availableVersions);
21875
21907
  }
21876
21908
  async function scanParentDirs(destPath, readPackageJson = false) {
21877
21909
  (0, import_assert6.default)(import_path5.default.isAbsolute(destPath));
@@ -22271,23 +22303,23 @@ function getPrefixedEnvVars({
22271
22303
 
22272
22304
  // src/hard-link-dir.ts
22273
22305
  var import_path7 = __toESM(require("path"));
22274
- var import_fs = require("fs");
22306
+ var import_fs2 = require("fs");
22275
22307
  async function hardLinkDir(src, destDirs) {
22276
22308
  if (destDirs.length === 0)
22277
22309
  return;
22278
22310
  destDirs = destDirs.filter((destDir) => import_path7.default.relative(destDir, src) !== "");
22279
- const files = await import_fs.promises.readdir(src);
22311
+ const files = await import_fs2.promises.readdir(src);
22280
22312
  await Promise.all(
22281
22313
  files.map(async (file) => {
22282
22314
  if (file === "node_modules")
22283
22315
  return;
22284
22316
  const srcFile = import_path7.default.join(src, file);
22285
- if ((await import_fs.promises.lstat(srcFile)).isDirectory()) {
22317
+ if ((await import_fs2.promises.lstat(srcFile)).isDirectory()) {
22286
22318
  const destSubdirs = await Promise.all(
22287
22319
  destDirs.map(async (destDir) => {
22288
22320
  const destSubdir = import_path7.default.join(destDir, file);
22289
22321
  try {
22290
- await import_fs.promises.mkdir(destSubdir, { recursive: true });
22322
+ await import_fs2.promises.mkdir(destSubdir, { recursive: true });
22291
22323
  } catch (err) {
22292
22324
  if (err.code !== "EEXIST")
22293
22325
  throw err;
@@ -22319,7 +22351,7 @@ async function linkOrCopyFile(srcFile, destFile) {
22319
22351
  await linkOrCopy(srcFile, destFile);
22320
22352
  } catch (err) {
22321
22353
  if (err.code === "ENOENT") {
22322
- 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 });
22323
22355
  await linkOrCopy(srcFile, destFile);
22324
22356
  return;
22325
22357
  }
@@ -22330,11 +22362,11 @@ async function linkOrCopyFile(srcFile, destFile) {
22330
22362
  }
22331
22363
  async function linkOrCopy(srcFile, destFile) {
22332
22364
  try {
22333
- await import_fs.promises.link(srcFile, destFile);
22365
+ await import_fs2.promises.link(srcFile, destFile);
22334
22366
  } catch (err) {
22335
22367
  if (err.code !== "EXDEV")
22336
22368
  throw err;
22337
- await import_fs.promises.copyFile(srcFile, destFile);
22369
+ await import_fs2.promises.copyFile(srcFile, destFile);
22338
22370
  }
22339
22371
  }
22340
22372
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "7.2.2",
3
+ "version": "7.2.4",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",
@@ -26,7 +26,7 @@
26
26
  "@types/node-fetch": "^2.1.6",
27
27
  "@types/semver": "6.0.0",
28
28
  "@types/yazl": "2.4.2",
29
- "@vercel/error-utils": "2.0.1",
29
+ "@vercel/error-utils": "2.0.2",
30
30
  "aggregate-error": "3.0.1",
31
31
  "async-retry": "1.2.3",
32
32
  "async-sema": "2.1.4",
@@ -50,6 +50,7 @@
50
50
  "build": "node build.mjs",
51
51
  "test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
52
52
  "test-unit": "pnpm test test/unit.*test.*",
53
- "test-e2e": "pnpm test test/integration.test.ts"
53
+ "test-e2e": "pnpm test test/integration.test.ts",
54
+ "type-check": "tsc --noEmit"
54
55
  }
55
56
  }