@vercel/build-utils 7.5.0 → 7.6.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,25 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 7.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Revert "Default ruby to only currently supported version (3.2.0)" ([#11135](https://github.com/vercel/vercel/pull/11135))
8
+
9
+ - Mark `flags` as deprecated and replace them with `variants` ([#11098](https://github.com/vercel/vercel/pull/11098))
10
+
11
+ - [build-utils] change default package manager when no lockfile detected from `yarn` to `npm` (gated behind feature flag) ([#11131](https://github.com/vercel/vercel/pull/11131))
12
+
13
+ ### Patch Changes
14
+
15
+ - Update internal type for variants ([#11111](https://github.com/vercel/vercel/pull/11111))
16
+
17
+ ## 7.5.1
18
+
19
+ ### Patch Changes
20
+
21
+ - Add experimental field to Lambda and size to FileFsRef output ([#11059](https://github.com/vercel/vercel/pull/11059))
22
+
3
23
  ## 7.5.0
4
24
 
5
25
  ### Minor Changes
@@ -4,6 +4,7 @@ interface FileFsRefOptions {
4
4
  mode?: number;
5
5
  contentType?: string;
6
6
  fsPath: string;
7
+ size?: number;
7
8
  }
8
9
  interface FromStreamOptions {
9
10
  mode: number;
@@ -15,9 +16,10 @@ declare class FileFsRef implements FileBase {
15
16
  type: 'FileFsRef';
16
17
  mode: number;
17
18
  fsPath: string;
19
+ size?: number;
18
20
  contentType: string | undefined;
19
- constructor({ mode, contentType, fsPath }: FileFsRefOptions);
20
- static fromFsPath({ mode, contentType, fsPath, }: FileFsRefOptions): Promise<FileFsRef>;
21
+ constructor({ mode, contentType, fsPath, size, }: FileFsRefOptions);
22
+ static fromFsPath({ mode, contentType, fsPath, size, }: FileFsRefOptions): Promise<FileFsRef>;
21
23
  static fromStream({ mode, contentType, stream, fsPath, }: FromStreamOptions): Promise<FileFsRef>;
22
24
  toStreamAsync(): Promise<NodeJS.ReadableStream>;
23
25
  toStream(): NodeJS.ReadableStream;
@@ -38,25 +38,34 @@ var import_path = __toESM(require("path"));
38
38
  var import_async_sema = __toESM(require("async-sema"));
39
39
  const semaToPreventEMFILE = new import_async_sema.default(20);
40
40
  class FileFsRef {
41
- constructor({ mode = 33188, contentType, fsPath }) {
41
+ constructor({
42
+ mode = 33188,
43
+ contentType,
44
+ fsPath,
45
+ size
46
+ }) {
42
47
  (0, import_assert.default)(typeof mode === "number");
43
48
  (0, import_assert.default)(typeof fsPath === "string");
44
49
  this.type = "FileFsRef";
45
50
  this.mode = mode;
46
51
  this.contentType = contentType;
47
52
  this.fsPath = fsPath;
53
+ this.size = size;
48
54
  }
49
55
  static async fromFsPath({
50
56
  mode,
51
57
  contentType,
52
- fsPath
58
+ fsPath,
59
+ size
53
60
  }) {
54
61
  let m = mode;
55
- if (!m) {
62
+ let s = size;
63
+ if (!m || typeof s === "undefined") {
56
64
  const stat = await import_fs_extra.default.lstat(fsPath);
57
65
  m = stat.mode;
66
+ s = stat.size;
58
67
  }
59
- return new FileFsRef({ mode: m, contentType, fsPath });
68
+ return new FileFsRef({ mode: m, contentType, fsPath, size: s });
60
69
  }
61
70
  static async fromStream({
62
71
  mode = 33188,
@@ -77,7 +86,7 @@ class FileFsRef {
77
86
  dest.on("finish", resolve);
78
87
  dest.on("error", reject);
79
88
  });
80
- return new FileFsRef({ mode, contentType, fsPath });
89
+ return FileFsRef.fromFsPath({ mode, contentType, fsPath });
81
90
  }
82
91
  async toStreamAsync() {
83
92
  await semaToPreventEMFILE.acquire();
@@ -220,7 +220,7 @@ async function scanParentDirs(destPath, readPackageJson = false) {
220
220
  });
221
221
  let lockfilePath;
222
222
  let lockfileVersion;
223
- let cliType = "yarn";
223
+ let cliType;
224
224
  const [hasYarnLock, packageLockJson, pnpmLockYaml, bunLockBin] = await Promise.all([
225
225
  Boolean(yarnLockPath),
226
226
  npmLockPath ? (0, import_read_config_file.readConfigFile)(npmLockPath) : null,
@@ -246,6 +246,12 @@ async function scanParentDirs(destPath, readPackageJson = false) {
246
246
  cliType = "bun";
247
247
  lockfilePath = bunLockPath;
248
248
  lockfileVersion = 0;
249
+ } else {
250
+ if (process.env.VERCEL_ENABLE_NPM_DEFAULT === "1") {
251
+ cliType = "npm";
252
+ } else {
253
+ cliType = "yarn";
254
+ }
249
255
  }
250
256
  const packageJsonPath = pkgJsonPath || void 0;
251
257
  return {
@@ -302,6 +308,13 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
302
308
  const { cliType, packageJsonPath, lockfileVersion } = await scanParentDirs(
303
309
  destPath
304
310
  );
311
+ if (!packageJsonPath) {
312
+ (0, import_debug.default)(
313
+ `Skipping dependency installation because no package.json was found for ${destPath}`
314
+ );
315
+ runNpmInstallSema.release();
316
+ return false;
317
+ }
305
318
  if (meta && packageJsonPath && args.length === 0) {
306
319
  if (!isSet(meta.runNpmInstallSet)) {
307
320
  meta.runNpmInstallSet = /* @__PURE__ */ new Set();
package/dist/index.js CHANGED
@@ -20810,25 +20810,34 @@ var import_path = __toESM(require("path"));
20810
20810
  var import_async_sema = __toESM(require_async_sema());
20811
20811
  var semaToPreventEMFILE = new import_async_sema.default(20);
20812
20812
  var FileFsRef = class _FileFsRef {
20813
- constructor({ mode = 33188, contentType, fsPath }) {
20813
+ constructor({
20814
+ mode = 33188,
20815
+ contentType,
20816
+ fsPath,
20817
+ size
20818
+ }) {
20814
20819
  (0, import_assert2.default)(typeof mode === "number");
20815
20820
  (0, import_assert2.default)(typeof fsPath === "string");
20816
20821
  this.type = "FileFsRef";
20817
20822
  this.mode = mode;
20818
20823
  this.contentType = contentType;
20819
20824
  this.fsPath = fsPath;
20825
+ this.size = size;
20820
20826
  }
20821
20827
  static async fromFsPath({
20822
20828
  mode,
20823
20829
  contentType,
20824
- fsPath
20830
+ fsPath,
20831
+ size
20825
20832
  }) {
20826
20833
  let m = mode;
20827
- if (!m) {
20834
+ let s = size;
20835
+ if (!m || typeof s === "undefined") {
20828
20836
  const stat = await import_fs_extra.default.lstat(fsPath);
20829
20837
  m = stat.mode;
20838
+ s = stat.size;
20830
20839
  }
20831
- return new _FileFsRef({ mode: m, contentType, fsPath });
20840
+ return new _FileFsRef({ mode: m, contentType, fsPath, size: s });
20832
20841
  }
20833
20842
  static async fromStream({
20834
20843
  mode = 33188,
@@ -20849,7 +20858,7 @@ var FileFsRef = class _FileFsRef {
20849
20858
  dest.on("finish", resolve);
20850
20859
  dest.on("error", reject);
20851
20860
  });
20852
- return new _FileFsRef({ mode, contentType, fsPath });
20861
+ return _FileFsRef.fromFsPath({ mode, contentType, fsPath });
20853
20862
  }
20854
20863
  async toStreamAsync() {
20855
20864
  await semaToPreventEMFILE.acquire();
@@ -21208,6 +21217,12 @@ var Lambda = class {
21208
21217
  '"architecture" must be either "x86_64" or "arm64"'
21209
21218
  );
21210
21219
  }
21220
+ if ("experimentalAllowBundling" in opts && opts.experimentalAllowBundling !== void 0) {
21221
+ (0, import_assert4.default)(
21222
+ typeof opts.experimentalAllowBundling === "boolean",
21223
+ '"experimentalAllowBundling" is not a boolean'
21224
+ );
21225
+ }
21211
21226
  if (memory !== void 0) {
21212
21227
  (0, import_assert4.default)(typeof memory === "number", '"memory" is not a number');
21213
21228
  }
@@ -21269,6 +21284,7 @@ var Lambda = class {
21269
21284
  this.supportsWrapper = supportsWrapper;
21270
21285
  this.supportsResponseStreaming = supportsResponseStreaming ?? experimentalResponseStreaming;
21271
21286
  this.framework = framework;
21287
+ this.experimentalAllowBundling = "experimentalAllowBundling" in opts ? opts.experimentalAllowBundling : void 0;
21272
21288
  }
21273
21289
  async createZip() {
21274
21290
  let { zipBuffer } = this;
@@ -21923,7 +21939,7 @@ async function scanParentDirs(destPath, readPackageJson = false) {
21923
21939
  });
21924
21940
  let lockfilePath;
21925
21941
  let lockfileVersion;
21926
- let cliType = "yarn";
21942
+ let cliType;
21927
21943
  const [hasYarnLock, packageLockJson, pnpmLockYaml, bunLockBin] = await Promise.all([
21928
21944
  Boolean(yarnLockPath),
21929
21945
  npmLockPath ? readConfigFile(npmLockPath) : null,
@@ -21949,6 +21965,12 @@ async function scanParentDirs(destPath, readPackageJson = false) {
21949
21965
  cliType = "bun";
21950
21966
  lockfilePath = bunLockPath;
21951
21967
  lockfileVersion = 0;
21968
+ } else {
21969
+ if (process.env.VERCEL_ENABLE_NPM_DEFAULT === "1") {
21970
+ cliType = "npm";
21971
+ } else {
21972
+ cliType = "yarn";
21973
+ }
21952
21974
  }
21953
21975
  const packageJsonPath = pkgJsonPath || void 0;
21954
21976
  return {
@@ -22005,6 +22027,13 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, nodeVersion)
22005
22027
  const { cliType, packageJsonPath, lockfileVersion } = await scanParentDirs(
22006
22028
  destPath
22007
22029
  );
22030
+ if (!packageJsonPath) {
22031
+ debug(
22032
+ `Skipping dependency installation because no package.json was found for ${destPath}`
22033
+ );
22034
+ runNpmInstallSema.release();
22035
+ return false;
22036
+ }
22008
22037
  if (meta && packageJsonPath && args.length === 0) {
22009
22038
  if (!isSet(meta.runNpmInstallSet)) {
22010
22039
  meta.runNpmInstallSet = /* @__PURE__ */ new Set();
package/dist/lambda.d.ts CHANGED
@@ -26,6 +26,7 @@ export interface LambdaOptionsBase {
26
26
  }
27
27
  export interface LambdaOptionsWithFiles extends LambdaOptionsBase {
28
28
  files: Files;
29
+ experimentalAllowBundling?: boolean;
29
30
  }
30
31
  /**
31
32
  * @deprecated Use `LambdaOptionsWithFiles` instead.
@@ -65,6 +66,7 @@ export declare class Lambda {
65
66
  supportsWrapper?: boolean;
66
67
  supportsResponseStreaming?: boolean;
67
68
  framework?: FunctionFramework;
69
+ experimentalAllowBundling?: boolean;
68
70
  constructor(opts: LambdaOptions);
69
71
  createZip(): Promise<Buffer>;
70
72
  /**
package/dist/lambda.js CHANGED
@@ -74,6 +74,12 @@ class Lambda {
74
74
  '"architecture" must be either "x86_64" or "arm64"'
75
75
  );
76
76
  }
77
+ if ("experimentalAllowBundling" in opts && opts.experimentalAllowBundling !== void 0) {
78
+ (0, import_assert.default)(
79
+ typeof opts.experimentalAllowBundling === "boolean",
80
+ '"experimentalAllowBundling" is not a boolean'
81
+ );
82
+ }
77
83
  if (memory !== void 0) {
78
84
  (0, import_assert.default)(typeof memory === "number", '"memory" is not a number');
79
85
  }
@@ -135,6 +141,7 @@ class Lambda {
135
141
  this.supportsWrapper = supportsWrapper;
136
142
  this.supportsResponseStreaming = supportsResponseStreaming ?? experimentalResponseStreaming;
137
143
  this.framework = framework;
144
+ this.experimentalAllowBundling = "experimentalAllowBundling" in opts ? opts.experimentalAllowBundling : void 0;
138
145
  }
139
146
  async createZip() {
140
147
  let { zipBuffer } = this;
package/dist/types.d.ts CHANGED
@@ -385,6 +385,9 @@ export interface Cron {
385
385
  path: string;
386
386
  schedule: string;
387
387
  }
388
+ /**
389
+ * @deprecated Replaced by Variants. Remove once fully replaced.
390
+ */
388
391
  export interface Flag {
389
392
  key: string;
390
393
  defaultValue?: unknown;
@@ -412,7 +415,9 @@ export interface BuildResultV2Typical {
412
415
  framework?: {
413
416
  version: string;
414
417
  };
418
+ /** @deprecated Replaced by Variants. Remove once fully replaced. */
415
419
  flags?: Flag[];
420
+ variants?: Record<string, VariantDefinition>;
416
421
  }
417
422
  export type BuildResultV2 = BuildResultV2Typical | BuildResultBuildOutput;
418
423
  export interface BuildResultV3 {
@@ -424,4 +429,21 @@ export type BuildV3 = (options: BuildOptions) => Promise<BuildResultV3>;
424
429
  export type PrepareCache = (options: PrepareCacheOptions) => Promise<Files>;
425
430
  export type ShouldServe = (options: ShouldServeOptions) => boolean | Promise<boolean>;
426
431
  export type StartDevServer = (options: StartDevServerOptions) => Promise<StartDevServerResult>;
432
+ /**
433
+ * TODO: The following types will eventually be exported by a more
434
+ * relevant package.
435
+ */
436
+ type VariantJSONArray = ReadonlyArray<VariantJSONValue>;
437
+ type VariantJSONValue = string | boolean | number | null | VariantJSONArray | {
438
+ [key: string]: VariantJSONValue;
439
+ };
440
+ type VariantOption = {
441
+ value: VariantJSONValue;
442
+ label?: string;
443
+ };
444
+ export interface VariantDefinition {
445
+ options?: VariantOption[];
446
+ origin?: string;
447
+ description?: string;
448
+ }
427
449
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",