@vercel/build-utils 13.4.3 → 13.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,35 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 13.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Find entrypoints for django projects. ([#15167](https://github.com/vercel/vercel/pull/15167))
8
+
9
+ ### Patch Changes
10
+
11
+ - Rename fetch to nodeFetch in cases where it is an import from node-fetch ([#15234](https://github.com/vercel/vercel/pull/15234))
12
+
13
+ - [@vercel/build-utils] fix uncaught exception in streamToBuffer when stream exceeds max Buffer size ([#15276](https://github.com/vercel/vercel/pull/15276))
14
+
15
+ - Remove source and destination typo suggestions for routes schema ([#15014](https://github.com/vercel/vercel/pull/15014))
16
+
17
+ - Support function overrides in backends builder ([#15214](https://github.com/vercel/vercel/pull/15214))
18
+
19
+ - Updated dependencies [[`b3a96cc4f276ce8d16c695eabd499d3a17e73aa8`](https://github.com/vercel/vercel/commit/b3a96cc4f276ce8d16c695eabd499d3a17e73aa8)]:
20
+ - @vercel/python-analysis@0.8.0
21
+
22
+ ## 13.5.0
23
+
24
+ ### Minor Changes
25
+
26
+ - Add django experimental framework. ([#15196](https://github.com/vercel/vercel/pull/15196))
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [[`cb79f6f8080fddd3673a8911566085e0265b060b`](https://github.com/vercel/vercel/commit/cb79f6f8080fddd3673a8911566085e0265b060b)]:
31
+ - @vercel/python-analysis@0.7.0
32
+
3
33
  ## 13.4.3
4
34
 
5
35
  ### Patch Changes
package/dist/errors.js CHANGED
@@ -77,8 +77,6 @@ const mapTypoToSuggestion = {
77
77
  redirects: { src: "source", dest: "destination", status: "statusCode" },
78
78
  headers: { src: "source", header: "headers" },
79
79
  routes: {
80
- source: "src",
81
- destination: "dest",
82
80
  header: "headers",
83
81
  method: "methods"
84
82
  }
@@ -42,15 +42,19 @@ function streamToBuffer(stream) {
42
42
  reject(err);
43
43
  return;
44
44
  }
45
- switch (buffers.length) {
46
- case 0:
47
- resolve(Buffer.allocUnsafe(0));
48
- break;
49
- case 1:
50
- resolve(buffers[0]);
51
- break;
52
- default:
53
- resolve(Buffer.concat(buffers));
45
+ try {
46
+ switch (buffers.length) {
47
+ case 0:
48
+ resolve(Buffer.allocUnsafe(0));
49
+ break;
50
+ case 1:
51
+ resolve(buffers[0]);
52
+ break;
53
+ default:
54
+ resolve(Buffer.concat(buffers));
55
+ }
56
+ } catch (concatErr) {
57
+ reject(concatErr);
54
58
  }
55
59
  });
56
60
  });
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import FileBlob from './file-blob';
2
2
  import FileFsRef from './file-fs-ref';
3
3
  import FileRef from './file-ref';
4
4
  import { Lambda, createLambda, getLambdaOptionsFromFunction, sanitizeConsumerName } from './lambda';
5
- import { NodejsLambda } from './nodejs-lambda';
5
+ import { NodejsLambda, type NodejsLambdaOptions } from './nodejs-lambda';
6
6
  import { Prerender } from './prerender';
7
7
  import download, { downloadFile, DownloadedFiles, isSymbolicLink, isDirectory } from './fs/download';
8
8
  import getWriteableDirectory from './fs/get-writable-directory';
@@ -19,6 +19,7 @@ import { getServiceUrlEnvVars } from './get-service-url-env-vars';
19
19
  import { cloneEnv } from './clone-env';
20
20
  import { hardLinkDir } from './hard-link-dir';
21
21
  import { validateNpmrc } from './validate-npmrc';
22
+ export type { NodejsLambdaOptions };
22
23
  export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, downloadFile, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, getNodeBinPaths, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion, detectPackageManager, runNpmInstall, NpmInstallOutput, runBundleInstall, runPipInstall, PipInstallResult, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, getPrefixedEnvVars, getServiceUrlEnvVars, streamToBuffer, streamToBufferChunks, debug, isSymbolicLink, isDirectory, getLambdaOptionsFromFunction, sanitizeConsumerName, scanParentDirs, findPackageJson, getIgnoreFilter, cloneEnv, hardLinkDir, traverseUpDirectories, validateNpmrc, };
23
24
  export { EdgeFunction } from './edge-function';
24
25
  export { readConfigFile, getPackageJson } from './fs/read-config-file';
package/dist/index.js CHANGED
@@ -318,7 +318,7 @@ var require_BufferList = __commonJS({
318
318
  this.head = this.tail = null;
319
319
  this.length = 0;
320
320
  };
321
- BufferList.prototype.join = function join5(s) {
321
+ BufferList.prototype.join = function join6(s) {
322
322
  if (this.length === 0)
323
323
  return "";
324
324
  var p = this.head;
@@ -8186,12 +8186,12 @@ var require_lib3 = __commonJS({
8186
8186
  const dest = new URL$1(destination).hostname;
8187
8187
  return orig === dest || orig[orig.length - dest.length - 1] === "." && orig.endsWith(dest);
8188
8188
  };
8189
- function fetch2(url, opts) {
8190
- if (!fetch2.Promise) {
8189
+ function fetch(url, opts) {
8190
+ if (!fetch.Promise) {
8191
8191
  throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
8192
8192
  }
8193
- Body.Promise = fetch2.Promise;
8194
- return new fetch2.Promise(function(resolve, reject) {
8193
+ Body.Promise = fetch.Promise;
8194
+ return new fetch.Promise(function(resolve, reject) {
8195
8195
  const request = new Request(url, opts);
8196
8196
  const options = getNodeRequestOptions(request);
8197
8197
  const send = (options.protocol === "https:" ? https : http).request;
@@ -8241,7 +8241,7 @@ var require_lib3 = __commonJS({
8241
8241
  req.on("response", function(res) {
8242
8242
  clearTimeout(reqTimeout);
8243
8243
  const headers = createHeadersLenient(res.headers);
8244
- if (fetch2.isRedirect(res.statusCode)) {
8244
+ if (fetch.isRedirect(res.statusCode)) {
8245
8245
  const location = headers.get("Location");
8246
8246
  let locationURL = null;
8247
8247
  try {
@@ -8303,7 +8303,7 @@ var require_lib3 = __commonJS({
8303
8303
  requestOpts.body = void 0;
8304
8304
  requestOpts.headers.delete("content-length");
8305
8305
  }
8306
- resolve(fetch2(new Request(locationURL, requestOpts)));
8306
+ resolve(fetch(new Request(locationURL, requestOpts)));
8307
8307
  finalize();
8308
8308
  return;
8309
8309
  }
@@ -8363,11 +8363,11 @@ var require_lib3 = __commonJS({
8363
8363
  writeToStream(req, request);
8364
8364
  });
8365
8365
  }
8366
- fetch2.isRedirect = function(code) {
8366
+ fetch.isRedirect = function(code) {
8367
8367
  return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
8368
8368
  };
8369
- fetch2.Promise = global.Promise;
8370
- module2.exports = exports2 = fetch2;
8369
+ fetch.Promise = global.Promise;
8370
+ module2.exports = exports2 = fetch;
8371
8371
  Object.defineProperty(exports2, "__esModule", { value: true });
8372
8372
  exports2.default = exports2;
8373
8373
  exports2.Headers = Headers;
@@ -21849,6 +21849,8 @@ __export(src_exports, {
21849
21849
  functionsSchema: () => functionsSchema,
21850
21850
  generateNodeBuilderFunctions: () => generateNodeBuilderFunctions,
21851
21851
  getDiscontinuedNodeVersions: () => getDiscontinuedNodeVersions,
21852
+ getDjangoEntrypoint: () => getDjangoEntrypoint,
21853
+ getDjangoSettingsModule: () => getDjangoSettingsModule,
21852
21854
  getEnvForPackageManager: () => getEnvForPackageManager,
21853
21855
  getIgnoreFilter: () => get_ignore_filter_default,
21854
21856
  getInstalledPackageVersion: () => getInstalledPackageVersion,
@@ -22213,8 +22215,6 @@ var mapTypoToSuggestion = {
22213
22215
  redirects: { src: "source", dest: "destination", status: "statusCode" },
22214
22216
  headers: { src: "source", header: "headers" },
22215
22217
  routes: {
22216
- source: "src",
22217
- destination: "dest",
22218
22218
  header: "headers",
22219
22219
  method: "methods"
22220
22220
  }
@@ -22267,15 +22267,19 @@ function streamToBuffer(stream) {
22267
22267
  reject(err);
22268
22268
  return;
22269
22269
  }
22270
- switch (buffers.length) {
22271
- case 0:
22272
- resolve(Buffer.allocUnsafe(0));
22273
- break;
22274
- case 1:
22275
- resolve(buffers[0]);
22276
- break;
22277
- default:
22278
- resolve(Buffer.concat(buffers));
22270
+ try {
22271
+ switch (buffers.length) {
22272
+ case 0:
22273
+ resolve(Buffer.allocUnsafe(0));
22274
+ break;
22275
+ case 1:
22276
+ resolve(buffers[0]);
22277
+ break;
22278
+ default:
22279
+ resolve(Buffer.concat(buffers));
22280
+ }
22281
+ } catch (concatErr) {
22282
+ reject(concatErr);
22279
22283
  }
22280
22284
  });
22281
22285
  });
@@ -25111,6 +25115,7 @@ function shouldUseExperimentalBackends(framework) {
25111
25115
 
25112
25116
  // src/python.ts
25113
25117
  var import_fs3 = __toESM(require("fs"));
25118
+ var import_path11 = require("path");
25114
25119
  var import_python_analysis = require("@vercel/python-analysis");
25115
25120
  async function isPythonEntrypoint(file) {
25116
25121
  try {
@@ -25124,6 +25129,55 @@ async function isPythonEntrypoint(file) {
25124
25129
  return false;
25125
25130
  }
25126
25131
  }
25132
+ async function getDjangoSettingsModule(workPath) {
25133
+ const managePath = (0, import_path11.join)(workPath, "manage.py");
25134
+ try {
25135
+ const content = await import_fs3.default.promises.readFile(managePath, "utf-8");
25136
+ const value = await (0, import_python_analysis.parseDjangoSettingsModule)(content);
25137
+ if (value) {
25138
+ debug(`Django DJANGO_SETTINGS_MODULE from manage.py: ${value}`);
25139
+ return value;
25140
+ }
25141
+ } catch {
25142
+ debug("manage.py not found or unreadable, skipping Django settings module");
25143
+ }
25144
+ return null;
25145
+ }
25146
+ async function getDjangoEntrypoint(workPath) {
25147
+ const settingsModule = await getDjangoSettingsModule(workPath);
25148
+ if (!settingsModule)
25149
+ return null;
25150
+ const settingsPath = (0, import_path11.join)(
25151
+ workPath,
25152
+ `${settingsModule.replace(/\./g, "/")}.py`
25153
+ );
25154
+ try {
25155
+ const settingsContent = await import_fs3.default.promises.readFile(settingsPath, "utf-8");
25156
+ const asgiApplication = await (0, import_python_analysis.getStringConstant)(
25157
+ settingsContent,
25158
+ "ASGI_APPLICATION"
25159
+ );
25160
+ if (asgiApplication) {
25161
+ const modulePath = asgiApplication.split(".").slice(0, -1).join("/");
25162
+ const asgiPath = `${modulePath}.py`;
25163
+ debug(`Django ASGI entrypoint from ${settingsModule}: ${asgiPath}`);
25164
+ return asgiPath;
25165
+ }
25166
+ const wsgiApplication = await (0, import_python_analysis.getStringConstant)(
25167
+ settingsContent,
25168
+ "WSGI_APPLICATION"
25169
+ );
25170
+ if (wsgiApplication) {
25171
+ const modulePath = wsgiApplication.split(".").slice(0, -1).join("/");
25172
+ const wsgiPath = `${modulePath}.py`;
25173
+ debug(`Django WSGI entrypoint from ${settingsModule}: ${wsgiPath}`);
25174
+ return wsgiPath;
25175
+ }
25176
+ } catch {
25177
+ debug(`Failed to read or parse settings file: ${settingsPath}`);
25178
+ }
25179
+ return null;
25180
+ }
25127
25181
  // Annotate the CommonJS export names for ESM import in node:
25128
25182
  0 && (module.exports = {
25129
25183
  BACKEND_BUILDERS,
@@ -25158,6 +25212,8 @@ async function isPythonEntrypoint(file) {
25158
25212
  functionsSchema,
25159
25213
  generateNodeBuilderFunctions,
25160
25214
  getDiscontinuedNodeVersions,
25215
+ getDjangoEntrypoint,
25216
+ getDjangoSettingsModule,
25161
25217
  getEnvForPackageManager,
25162
25218
  getIgnoreFilter,
25163
25219
  getInstalledPackageVersion,
@@ -1,5 +1,5 @@
1
1
  import { Lambda, LambdaOptionsWithFiles } from './lambda';
2
- interface NodejsLambdaOptions extends LambdaOptionsWithFiles {
2
+ export interface NodejsLambdaOptions extends LambdaOptionsWithFiles {
3
3
  shouldAddHelpers: boolean;
4
4
  shouldAddSourcemapSupport: boolean;
5
5
  awsLambdaHandler?: string;
@@ -13,4 +13,3 @@ export declare class NodejsLambda extends Lambda {
13
13
  useWebApi?: boolean;
14
14
  constructor({ shouldAddHelpers, shouldAddSourcemapSupport, awsLambdaHandler, useWebApi, ...opts }: NodejsLambdaOptions);
15
15
  }
16
- export {};
package/dist/python.d.ts CHANGED
@@ -8,3 +8,16 @@ import FileFsRef from './file-fs-ref';
8
8
  export declare function isPythonEntrypoint(file: FileFsRef | {
9
9
  fsPath?: string;
10
10
  }): Promise<boolean>;
11
+ /**
12
+ * For Django projects: read manage.py if present and return the value set for
13
+ * DJANGO_SETTINGS_MODULE (e.g. from os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')).
14
+ * Returns null if manage.py is missing or the pattern is not found.
15
+ */
16
+ export declare function getDjangoSettingsModule(workPath: string): Promise<string | null>;
17
+ /**
18
+ * For Django projects: resolve the ASGI or WSGI application entrypoint by reading
19
+ * DJANGO_SETTINGS_MODULE from manage.py, loading that settings file, and
20
+ * returning the file path for ASGI_APPLICATION or WSGI_APPLICATION (e.g.
21
+ * 'myapp.asgi.application' -> 'myapp/asgi.py'). Returns null if any step fails.
22
+ */
23
+ export declare function getDjangoEntrypoint(workPath: string): Promise<string | null>;
package/dist/python.js CHANGED
@@ -28,10 +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 python_exports = {};
30
30
  __export(python_exports, {
31
+ getDjangoEntrypoint: () => getDjangoEntrypoint,
32
+ getDjangoSettingsModule: () => getDjangoSettingsModule,
31
33
  isPythonEntrypoint: () => isPythonEntrypoint
32
34
  });
33
35
  module.exports = __toCommonJS(python_exports);
34
36
  var import_fs = __toESM(require("fs"));
37
+ var import_path = require("path");
35
38
  var import_python_analysis = require("@vercel/python-analysis");
36
39
  var import_debug = __toESM(require("./debug"));
37
40
  async function isPythonEntrypoint(file) {
@@ -46,7 +49,58 @@ async function isPythonEntrypoint(file) {
46
49
  return false;
47
50
  }
48
51
  }
52
+ async function getDjangoSettingsModule(workPath) {
53
+ const managePath = (0, import_path.join)(workPath, "manage.py");
54
+ try {
55
+ const content = await import_fs.default.promises.readFile(managePath, "utf-8");
56
+ const value = await (0, import_python_analysis.parseDjangoSettingsModule)(content);
57
+ if (value) {
58
+ (0, import_debug.default)(`Django DJANGO_SETTINGS_MODULE from manage.py: ${value}`);
59
+ return value;
60
+ }
61
+ } catch {
62
+ (0, import_debug.default)("manage.py not found or unreadable, skipping Django settings module");
63
+ }
64
+ return null;
65
+ }
66
+ async function getDjangoEntrypoint(workPath) {
67
+ const settingsModule = await getDjangoSettingsModule(workPath);
68
+ if (!settingsModule)
69
+ return null;
70
+ const settingsPath = (0, import_path.join)(
71
+ workPath,
72
+ `${settingsModule.replace(/\./g, "/")}.py`
73
+ );
74
+ try {
75
+ const settingsContent = await import_fs.default.promises.readFile(settingsPath, "utf-8");
76
+ const asgiApplication = await (0, import_python_analysis.getStringConstant)(
77
+ settingsContent,
78
+ "ASGI_APPLICATION"
79
+ );
80
+ if (asgiApplication) {
81
+ const modulePath = asgiApplication.split(".").slice(0, -1).join("/");
82
+ const asgiPath = `${modulePath}.py`;
83
+ (0, import_debug.default)(`Django ASGI entrypoint from ${settingsModule}: ${asgiPath}`);
84
+ return asgiPath;
85
+ }
86
+ const wsgiApplication = await (0, import_python_analysis.getStringConstant)(
87
+ settingsContent,
88
+ "WSGI_APPLICATION"
89
+ );
90
+ if (wsgiApplication) {
91
+ const modulePath = wsgiApplication.split(".").slice(0, -1).join("/");
92
+ const wsgiPath = `${modulePath}.py`;
93
+ (0, import_debug.default)(`Django WSGI entrypoint from ${settingsModule}: ${wsgiPath}`);
94
+ return wsgiPath;
95
+ }
96
+ } catch {
97
+ (0, import_debug.default)(`Failed to read or parse settings file: ${settingsPath}`);
98
+ }
99
+ return null;
100
+ }
49
101
  // Annotate the CommonJS export names for ESM import in node:
50
102
  0 && (module.exports = {
103
+ getDjangoEntrypoint,
104
+ getDjangoSettingsModule,
51
105
  isPythonEntrypoint
52
106
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "13.4.3",
3
+ "version": "13.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/now-build-utils"
12
12
  },
13
13
  "dependencies": {
14
- "@vercel/python-analysis": "0.6.0"
14
+ "@vercel/python-analysis": "0.8.0"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@iarna/toml": "2.2.3",
@@ -51,7 +51,7 @@
51
51
  "vitest": "2.0.1",
52
52
  "json5": "2.2.3",
53
53
  "@vercel/error-utils": "2.0.3",
54
- "@vercel/routing-utils": "5.3.3"
54
+ "@vercel/routing-utils": "6.0.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "node build.mjs",