@vercel/node 3.0.28 → 3.1.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.
@@ -248,20 +248,9 @@ var require_cookie = __commonJS({
248
248
  // src/serverless-functions/helpers-web.ts
249
249
  var helpers_web_exports = {};
250
250
  __export(helpers_web_exports, {
251
- getWebExportsHandler: () => getWebExportsHandler
251
+ createWebExportsHandler: () => createWebExportsHandler
252
252
  });
253
253
  import { buildToNodeHandler } from "@edge-runtime/node-utils";
254
- import Edge from "@edge-runtime/primitives";
255
- function getWebExportsHandler(listener, methods) {
256
- const handlerByMethod = {};
257
- for (const key of methods) {
258
- handlerByMethod[key] = typeof listener[key] !== "undefined" ? webHandlerToNodeHandler(listener[key]) : defaultHttpHandler;
259
- }
260
- return (req, res) => {
261
- const method = req.method ?? "GET";
262
- handlerByMethod[method](req, res);
263
- };
264
- }
265
254
  function addDuplexToInit(init2) {
266
255
  if (typeof init2 === "undefined" || typeof init2 === "object") {
267
256
  return { duplex: "half", ...init2 };
@@ -272,25 +261,43 @@ function defaultHttpHandler(_, res) {
272
261
  res.statusCode = 405;
273
262
  res.end();
274
263
  }
275
- var webHandlerToNodeHandler;
264
+ var createWebExportsHandler;
276
265
  var init_helpers_web = __esm({
277
266
  "src/serverless-functions/helpers-web.ts"() {
278
267
  "use strict";
279
- webHandlerToNodeHandler = buildToNodeHandler(
280
- {
281
- Headers,
282
- ReadableStream,
283
- // @ts-expect-error Property 'duplex' is missing in type 'Request'
284
- Request: class extends Request {
285
- constructor(input, init2) {
286
- super(input, addDuplexToInit(init2));
268
+ createWebExportsHandler = (awaiter) => {
269
+ const webHandlerToNodeHandler = buildToNodeHandler(
270
+ {
271
+ Headers,
272
+ ReadableStream,
273
+ // @ts-expect-error Property 'duplex' is missing in type 'Request'
274
+ Request: class extends Request {
275
+ constructor(input, init2) {
276
+ super(input, addDuplexToInit(init2));
277
+ }
278
+ },
279
+ Uint8Array,
280
+ // @ts-expect-error Property 'waitUntil' is missing in type 'FetchEvent'
281
+ FetchEvent: class {
282
+ constructor() {
283
+ this.waitUntil = (promise) => awaiter.waitUntil(promise);
284
+ }
287
285
  }
288
286
  },
289
- Uint8Array,
290
- FetchEvent: Edge.FetchEvent
291
- },
292
- { defaultOrigin: "https://vercel.com" }
293
- );
287
+ { defaultOrigin: "https://vercel.com" }
288
+ );
289
+ function getWebExportsHandler(listener, methods) {
290
+ const handlerByMethod = {};
291
+ for (const key of methods) {
292
+ handlerByMethod[key] = typeof listener[key] !== "undefined" ? webHandlerToNodeHandler(listener[key]) : defaultHttpHandler;
293
+ }
294
+ return (req, res) => {
295
+ const method = req.method ?? "GET";
296
+ handlerByMethod[method](req, res);
297
+ };
298
+ }
299
+ return getWebExportsHandler;
300
+ };
294
301
  }
295
302
  });
296
303
 
@@ -524,6 +531,12 @@ import { readFileSync } from "fs";
524
531
  import { debug, streamToBuffer } from "@vercel/build-utils";
525
532
  import { pathToRegexp } from "path-to-regexp";
526
533
  import { extname } from "path";
534
+ var WAIT_UNTIL_TIMEOUT = 10;
535
+ var WAIT_UNTIL_TIMEOUT_MS = 10 * 1e3;
536
+ var waitUntilWarning = (entrypointPath) => `
537
+ The function \`${entrypointPath.split("/").pop()}\` is still running after ${WAIT_UNTIL_TIMEOUT}s.
538
+ (hint: do you have a long-running waitUntil() promise?)
539
+ `.trim();
527
540
  function entrypointToOutputPath(entrypoint2, zeroConfig) {
528
541
  if (zeroConfig) {
529
542
  const ext = extname(entrypoint2);
@@ -578,6 +591,31 @@ async function serializeBody(request) {
578
591
  import esbuild from "esbuild";
579
592
  import { buildToHeaders } from "@edge-runtime/node-utils";
580
593
  import { fileURLToPath } from "url";
594
+
595
+ // src/awaiter.ts
596
+ var Awaiter = class {
597
+ constructor({ onError } = {}) {
598
+ this.promises = /* @__PURE__ */ new Set();
599
+ this.awaiting = () => this.waitForBatch().then(
600
+ () => this.promises.size > 0 ? this.waitForBatch() : Promise.resolve()
601
+ );
602
+ this.waitUntil = (promise) => {
603
+ this.promises.add(promise);
604
+ };
605
+ this.waitForBatch = async () => {
606
+ const promises = Array.from(this.promises);
607
+ this.promises.clear();
608
+ await Promise.all(
609
+ promises.map(
610
+ (promise) => Promise.resolve(promise).then(() => void 0, this.onError)
611
+ )
612
+ );
613
+ };
614
+ this.onError = onError ?? console.error;
615
+ }
616
+ };
617
+
618
+ // src/edge-functions/edge-handler.mts
581
619
  var NODE_VERSION_MAJOR = process.version.match(/^v(\d+)\.\d+/)?.[1];
582
620
  var NODE_VERSION_IDENTIFIER = `node${NODE_VERSION_MAJOR}`;
583
621
  if (!NODE_VERSION_MAJOR) {
@@ -655,9 +693,11 @@ async function compileUserCode(entrypointFullPath, entrypointRelativePath, isMid
655
693
  registerFetchListener(userModule, options, dependencies);
656
694
  `;
657
695
  return {
696
+ entrypointPath: entrypointFullPath,
658
697
  userCode,
659
698
  wasmAssets,
660
- nodeCompatBindings: nodeCompatPlugin.bindings
699
+ nodeCompatBindings: nodeCompatPlugin.bindings,
700
+ awaiter: new Awaiter()
661
701
  };
662
702
  } catch (error) {
663
703
  console.error(`Failed to compile user code for edge runtime.`);
@@ -688,27 +728,32 @@ async function createEdgeRuntimeServer(params) {
688
728
  // These are the global bindings for Node.js compatibility
689
729
  ...nodeCompatBindings,
690
730
  // These are the global bindings for WebAssembly module
691
- ...wasmBindings
731
+ ...wasmBindings,
732
+ FetchEvent: class extends context.FetchEvent {
733
+ constructor() {
734
+ super(...arguments);
735
+ this.waitUntil = (promise) => {
736
+ params.awaiter.waitUntil(promise);
737
+ };
738
+ }
739
+ }
692
740
  });
693
741
  return context;
694
742
  }
695
743
  });
696
744
  const server = await runServer({ runtime });
697
- const onExit2 = async () => {
698
- const WAIT_UNTIL_TIMEOUT = 10 * 1e3;
699
- const waitUntil = server.close();
700
- return new Promise((resolve, reject) => {
701
- const timeout = setTimeout(() => {
702
- console.warn(
703
- `Edge Runtime server is still running after ${WAIT_UNTIL_TIMEOUT} ms (hint: do you have a long-running waitUntil() promise?)`
704
- );
705
- resolve();
706
- }, WAIT_UNTIL_TIMEOUT);
707
- waitUntil.then(() => resolve()).catch(reject).finally(() => {
708
- clearTimeout(timeout);
709
- });
710
- });
745
+ runtime.context.globalThis[Symbol.for("@vercel/request-context")] = {
746
+ get: () => ({
747
+ waitUntil: params.awaiter.waitUntil.bind(params.awaiter)
748
+ })
711
749
  };
750
+ const onExit2 = () => new Promise((resolve, reject) => {
751
+ const timeout = setTimeout(() => {
752
+ console.warn(waitUntilWarning(params.entrypointPath));
753
+ resolve();
754
+ }, WAIT_UNTIL_TIMEOUT_MS);
755
+ Promise.all([params.awaiter.awaiting(), server.close()]).then(() => resolve()).catch(reject).finally(() => clearTimeout(timeout));
756
+ });
712
757
  return { server, onExit: onExit2 };
713
758
  } catch (error) {
714
759
  console.error("Failed to instantiate edge runtime.");
@@ -985,6 +1030,7 @@ import { listen } from "async-listen";
985
1030
  import { isAbsolute } from "path";
986
1031
  import { pathToFileURL } from "url";
987
1032
  import { buildToHeaders as buildToHeaders2 } from "@edge-runtime/node-utils";
1033
+ import { promisify } from "util";
988
1034
  var toHeaders2 = buildToHeaders2({ Headers: Headers3 });
989
1035
  var [NODE_MAJOR] = process.versions.node.split(".").map((v) => Number(v));
990
1036
  var HTTP_METHODS = [
@@ -1000,12 +1046,10 @@ async function createServerlessServer(userCode) {
1000
1046
  const server = createServer(userCode);
1001
1047
  return {
1002
1048
  url: await listen(server, { host: "127.0.0.1", port: 0 }),
1003
- onExit: async () => {
1004
- server.close();
1005
- }
1049
+ onExit: promisify(server.close.bind(server))
1006
1050
  };
1007
1051
  }
1008
- async function compileUserCode2(entrypointPath, options) {
1052
+ async function compileUserCode2(entrypointPath, awaiter, options) {
1009
1053
  const id = isAbsolute(entrypointPath) ? pathToFileURL(entrypointPath).href : entrypointPath;
1010
1054
  let listener = await import(id);
1011
1055
  for (let i = 0; i < 5; i++) {
@@ -1018,8 +1062,9 @@ async function compileUserCode2(entrypointPath, options) {
1018
1062
  "Node.js v18 or above is required to use HTTP method exports in your functions."
1019
1063
  );
1020
1064
  }
1021
- const { getWebExportsHandler: getWebExportsHandler2 } = await Promise.resolve().then(() => (init_helpers_web(), helpers_web_exports));
1022
- return getWebExportsHandler2(listener, HTTP_METHODS);
1065
+ const { createWebExportsHandler: createWebExportsHandler2 } = await Promise.resolve().then(() => (init_helpers_web(), helpers_web_exports));
1066
+ const getWebExportsHandler = createWebExportsHandler2(awaiter);
1067
+ return getWebExportsHandler(listener, HTTP_METHODS);
1023
1068
  }
1024
1069
  return async (req, res) => {
1025
1070
  if (options.shouldAddHelpers)
@@ -1028,7 +1073,17 @@ async function compileUserCode2(entrypointPath, options) {
1028
1073
  };
1029
1074
  }
1030
1075
  async function createServerlessEventHandler(entrypointPath, options) {
1031
- const userCode = await compileUserCode2(entrypointPath, options);
1076
+ const awaiter = new Awaiter();
1077
+ Object.defineProperty(globalThis, Symbol.for("@vercel/request-context"), {
1078
+ enumerable: false,
1079
+ configurable: true,
1080
+ value: {
1081
+ get: () => ({
1082
+ waitUntil: awaiter.waitUntil.bind(awaiter)
1083
+ })
1084
+ }
1085
+ });
1086
+ const userCode = await compileUserCode2(entrypointPath, awaiter, options);
1032
1087
  const server = await createServerlessServer(userCode);
1033
1088
  const isStreaming = options.mode === "streaming";
1034
1089
  const handler = async function(request) {
@@ -1055,9 +1110,16 @@ async function createServerlessEventHandler(entrypointPath, options) {
1055
1110
  encoding: "utf8"
1056
1111
  };
1057
1112
  };
1113
+ const onExit2 = () => new Promise((resolve, reject) => {
1114
+ const timeout = setTimeout(() => {
1115
+ console.warn(waitUntilWarning(entrypointPath));
1116
+ resolve();
1117
+ }, WAIT_UNTIL_TIMEOUT_MS);
1118
+ Promise.all([awaiter.awaiting(), server.onExit()]).then(() => resolve()).catch(reject).finally(() => clearTimeout(timeout));
1119
+ });
1058
1120
  return {
1059
1121
  handler,
1060
- onExit: server.onExit
1122
+ onExit: onExit2
1061
1123
  };
1062
1124
  }
1063
1125
 
@@ -88,7 +88,12 @@ function registerFetchListener(module, options, dependencies) {
88
88
  `No default or HTTP-named export was found at ${url}. Add one to handle requests. Learn more: https://vercel.link/creating-edge-middleware`
89
89
  );
90
90
  }
91
- const response = await respond(handler, event, options, dependencies);
91
+ const response = await respond(
92
+ (req, ctx) => handler(req, { waitUntil: ctx.waitUntil.bind(ctx) }),
93
+ event,
94
+ options,
95
+ dependencies
96
+ );
92
97
  event.respondWith(response);
93
98
  } catch (error) {
94
99
  event.respondWith(toResponseError(error, dependencies.Response));
package/dist/index.js CHANGED
@@ -69912,6 +69912,7 @@ function filterDiagnostics(diagnostics, ignore) {
69912
69912
  var import_build_utils2 = require("@vercel/build-utils");
69913
69913
  var import_path_to_regexp = require("path-to-regexp");
69914
69914
  var import_path2 = require("path");
69915
+ var WAIT_UNTIL_TIMEOUT_MS = 10 * 1e3;
69915
69916
  function getRegExpFromMatchers(matcherOrMatchers) {
69916
69917
  if (!matcherOrMatchers) {
69917
69918
  return "^/.*$";
@@ -70007,9 +70008,18 @@ function forkDevServer(options) {
70007
70008
  TS_NODE_TRANSPILE_ONLY: "1",
70008
70009
  TS_NODE_COMPILER_OPTIONS: options.tsConfig?.compilerOptions ? JSON.stringify(options.tsConfig.compilerOptions) : void 0,
70009
70010
  NODE_OPTIONS: nodeOptions
70010
- })
70011
+ }),
70012
+ stdio: options.printLogs ? "pipe" : void 0
70011
70013
  };
70012
70014
  const child = (0, import_child_process.fork)(devServerPath, [], forkOptions);
70015
+ if (options.printLogs) {
70016
+ child.stdout?.on("data", (data) => {
70017
+ console.log(`stdout: ${data}`);
70018
+ });
70019
+ child.stderr?.on("data", (data) => {
70020
+ console.error(`stderr: ${data}`);
70021
+ });
70022
+ }
70013
70023
  checkForPid(devServerPath, child);
70014
70024
  return child;
70015
70025
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/node",
3
- "version": "3.0.28",
3
+ "version": "3.1.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -16,7 +16,7 @@
16
16
  "@edge-runtime/node-utils": "2.3.0",
17
17
  "@edge-runtime/primitives": "4.1.0",
18
18
  "@edge-runtime/vm": "3.2.0",
19
- "@types/node": "14.18.33",
19
+ "@types/node": "16.18.11",
20
20
  "@vercel/build-utils": "8.0.0",
21
21
  "@vercel/error-utils": "2.0.2",
22
22
  "@vercel/nft": "0.26.4",
@@ -50,7 +50,8 @@
50
50
  "fs-extra": "11.1.0",
51
51
  "jest-junit": "16.0.0",
52
52
  "source-map-support": "0.5.12",
53
- "tree-kill": "1.2.2"
53
+ "tree-kill": "1.2.2",
54
+ "@vercel/functions": "1.0.0"
54
55
  },
55
56
  "scripts": {
56
57
  "build": "node build.mjs",