@vercel/node 2.1.1-canary.0 → 2.2.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.
Files changed (2) hide show
  1. package/dist/dev-server.js +138 -31
  2. package/package.json +9 -6
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.fixConfigDev = exports.onDevRequest = exports.rawBody = void 0;
4
7
  const entrypoint = process.env.VERCEL_DEV_ENTRYPOINT;
@@ -60,6 +63,13 @@ if (!process.env.VERCEL_DEV_IS_ESM) {
60
63
  }
61
64
  const http_1 = require("http");
62
65
  const launcher_js_1 = require("@vercel/node-bridge/launcher.js");
66
+ const build_utils_1 = require("@vercel/build-utils");
67
+ const exit_hook_1 = __importDefault(require("exit-hook"));
68
+ const edge_runtime_1 = require("edge-runtime");
69
+ const static_config_1 = require("@vercel/static-config");
70
+ const ts_morph_1 = require("ts-morph");
71
+ const ncc_1 = __importDefault(require("@vercel/ncc"));
72
+ const node_fetch_1 = __importDefault(require("node-fetch"));
63
73
  function listen(server, port, host) {
64
74
  return new Promise(resolve => {
65
75
  server.listen(port, host, () => {
@@ -67,7 +77,119 @@ function listen(server, port, host) {
67
77
  });
68
78
  });
69
79
  }
70
- let bridge = undefined;
80
+ async function createServerlessEventHandler(entrypoint, options) {
81
+ const launcher = launcher_js_1.getVercelLauncher({
82
+ entrypointPath: entrypoint,
83
+ helpersPath: './helpers.js',
84
+ shouldAddHelpers: options.shouldAddHelpers,
85
+ useRequire,
86
+ // not used
87
+ bridgePath: '',
88
+ sourcemapSupportPath: '',
89
+ });
90
+ const bridge = launcher();
91
+ return async function (request) {
92
+ const body = await rawBody(request);
93
+ const event = {
94
+ Action: 'Invoke',
95
+ body: JSON.stringify({
96
+ method: request.method,
97
+ path: request.url,
98
+ headers: request.headers,
99
+ encoding: 'base64',
100
+ body: body.toString('base64'),
101
+ }),
102
+ };
103
+ return bridge.launcher(event, {
104
+ callbackWaitsForEmptyEventLoop: false,
105
+ });
106
+ };
107
+ }
108
+ async function serializeRequest(message) {
109
+ const bodyBuffer = await build_utils_1.streamToBuffer(message);
110
+ const body = bodyBuffer.toString('base64');
111
+ return JSON.stringify({
112
+ url: message.url,
113
+ method: message.method,
114
+ headers: message.headers,
115
+ body,
116
+ });
117
+ }
118
+ async function createEdgeEventHandler(entrypoint) {
119
+ const buildResult = await ncc_1.default(entrypoint, { target: 'es2022' });
120
+ const userCode = buildResult.code;
121
+ const initialCode = `
122
+ ${userCode};
123
+
124
+ addEventListener('fetch', async (event) => {
125
+ let serializedRequest = await event.request.text();
126
+ let requestDetails = JSON.parse(serializedRequest);
127
+
128
+ let body;
129
+
130
+ if (requestDetails.method !== 'GET' && requestDetails.method !== 'HEAD') {
131
+ body = Uint8Array.from(atob(requestDetails.body), c => c.charCodeAt(0));
132
+ }
133
+
134
+ let requestUrl = requestDetails.headers['x-forwarded-proto'] + '://' + requestDetails.headers['x-forwarded-host'] + requestDetails.url;
135
+
136
+ let request = new Request(requestUrl, {
137
+ headers: requestDetails.headers,
138
+ method: requestDetails.method,
139
+ body: body
140
+ });
141
+
142
+ event.request = request;
143
+
144
+ let edgeHandler = module.exports.default;
145
+ let response = edgeHandler(event.request, event);
146
+ return event.respondWith(response);
147
+ })`;
148
+ const edgeRuntime = new edge_runtime_1.EdgeRuntime({
149
+ initialCode,
150
+ extend: (context) => {
151
+ Object.assign(context, {
152
+ __dirname: '',
153
+ module: {
154
+ exports: {},
155
+ },
156
+ });
157
+ return context;
158
+ },
159
+ });
160
+ const server = await edge_runtime_1.runServer({ runtime: edgeRuntime });
161
+ exit_hook_1.default(server.close);
162
+ return async function (request) {
163
+ const response = await node_fetch_1.default(server.url, {
164
+ method: 'post',
165
+ body: await serializeRequest(request),
166
+ });
167
+ return {
168
+ statusCode: response.status,
169
+ headers: response.headers.raw(),
170
+ body: await response.text(),
171
+ encoding: 'utf8',
172
+ };
173
+ };
174
+ }
175
+ const validRuntimes = ['experimental-edge'];
176
+ function parseRuntime(entrypoint) {
177
+ const project = new ts_morph_1.Project();
178
+ const staticConfig = static_config_1.getConfig(project, entrypoint);
179
+ const runtime = staticConfig?.runtime;
180
+ if (runtime && !validRuntimes.includes(runtime)) {
181
+ throw new Error(`Invalid function runtime for "${entrypoint}": ${runtime}`);
182
+ }
183
+ return runtime;
184
+ }
185
+ async function createEventHandler(entrypoint, options) {
186
+ const runtime = parseRuntime(entrypoint);
187
+ if (runtime === 'experimental-edge') {
188
+ return createEdgeEventHandler(entrypoint);
189
+ }
190
+ return createServerlessEventHandler(entrypoint, options);
191
+ }
192
+ let handleEvent;
71
193
  async function main() {
72
194
  const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || '{}');
73
195
  delete process.env.VERCEL_DEV_CONFIG;
@@ -76,16 +198,8 @@ async function main() {
76
198
  const shouldAddHelpers = !(config.helpers === false || buildEnv.NODEJS_HELPERS === '0');
77
199
  const proxyServer = http_1.createServer(onDevRequest);
78
200
  await listen(proxyServer, 0, '127.0.0.1');
79
- const launcher = launcher_js_1.getVercelLauncher({
80
- entrypointPath: path_1.join(process.cwd(), entrypoint),
81
- helpersPath: './helpers.js',
82
- shouldAddHelpers,
83
- useRequire,
84
- // not used
85
- bridgePath: '',
86
- sourcemapSupportPath: '',
87
- });
88
- bridge = launcher();
201
+ const entryPointPath = path_1.join(process.cwd(), entrypoint);
202
+ handleEvent = await createEventHandler(entryPointPath, { shouldAddHelpers });
89
203
  const address = proxyServer.address();
90
204
  if (typeof process.send === 'function') {
91
205
  process.send(address);
@@ -110,32 +224,25 @@ function rawBody(readable) {
110
224
  }
111
225
  exports.rawBody = rawBody;
112
226
  async function onDevRequest(req, res) {
113
- const body = await rawBody(req);
114
- const event = {
115
- Action: 'Invoke',
116
- body: JSON.stringify({
117
- method: req.method,
118
- path: req.url,
119
- headers: req.headers,
120
- encoding: 'base64',
121
- body: body.toString('base64'),
122
- }),
123
- };
124
- if (!bridge) {
227
+ if (!handleEvent) {
125
228
  res.statusCode = 500;
126
229
  res.end('Bridge is not ready, please try again');
127
230
  return;
128
231
  }
129
- const result = await bridge.launcher(event, {
130
- callbackWaitsForEmptyEventLoop: false,
131
- });
132
- res.statusCode = result.statusCode;
133
- for (const [key, value] of Object.entries(result.headers)) {
134
- if (typeof value !== 'undefined') {
135
- res.setHeader(key, value);
232
+ try {
233
+ const result = await handleEvent(req);
234
+ res.statusCode = result.statusCode;
235
+ for (const [key, value] of Object.entries(result.headers)) {
236
+ if (typeof value !== 'undefined') {
237
+ res.setHeader(key, value);
238
+ }
136
239
  }
240
+ res.end(Buffer.from(result.body, result.encoding));
241
+ }
242
+ catch (error) {
243
+ res.statusCode = 500;
244
+ res.end(error.stack);
137
245
  }
138
- res.end(Buffer.from(result.body, result.encoding));
139
246
  }
140
247
  exports.onDevRequest = onDevRequest;
141
248
  function fixConfigDev(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/node",
3
- "version": "2.1.1-canary.0",
3
+ "version": "2.2.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -31,7 +31,13 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@types/node": "*",
34
+ "@vercel/build-utils": "4.1.1-canary.1",
35
+ "@vercel/ncc": "0.24.0",
34
36
  "@vercel/node-bridge": "3.0.0",
37
+ "@vercel/static-config": "2.0.1",
38
+ "edge-runtime": "1.0.1",
39
+ "exit-hook": "2.2.1",
40
+ "node-fetch": "2.6.1",
35
41
  "ts-node": "8.9.1",
36
42
  "typescript": "4.3.4"
37
43
  },
@@ -44,17 +50,14 @@
44
50
  "@types/cookie": "0.3.3",
45
51
  "@types/etag": "1.8.0",
46
52
  "@types/jest": "27.4.1",
53
+ "@types/node-fetch": "^2.6.1",
47
54
  "@types/test-listen": "1.1.0",
48
- "@vercel/build-utils": "4.1.1-canary.0",
49
- "@vercel/ncc": "0.24.0",
50
55
  "@vercel/nft": "0.19.1",
51
- "@vercel/static-config": "2.0.1",
52
56
  "content-type": "1.0.4",
53
57
  "cookie": "0.4.0",
54
58
  "etag": "1.8.1",
55
- "node-fetch": "2.6.1",
56
59
  "source-map-support": "0.5.12",
57
60
  "test-listen": "1.1.0"
58
61
  },
59
- "gitHead": "4bf6295d7a1d6544f195d76a2a4aedb476fa7dc1"
62
+ "gitHead": "0ace69ef754fd37a2df043e02a2278570c87ea32"
60
63
  }