@vercel/node 2.1.0 → 2.1.1-canary.2

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.
@@ -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/dist/index.js CHANGED
@@ -306748,28 +306748,50 @@ const build = async ({ files, entrypoint, workPath, repoRootPath, config = {}, m
306748
306748
  const traceTime = Date.now();
306749
306749
  const { preparedFiles, shouldAddSourcemapSupport } = await compile(workPath, baseDir, entrypointPath, config, nodeVersion);
306750
306750
  build_utils_1.debug(`Trace complete [${Date.now() - traceTime}ms]`);
306751
- const project = new ts_morph_1.Project();
306752
- const staticConfig = static_config_1.getConfig(project, entrypointPath);
306751
+ let routes;
306753
306752
  let output;
306754
306753
  const handler = renameTStoJS(path_1.relative(baseDir, entrypointPath));
306755
- if (staticConfig?.runtime) {
306756
- if (!ALLOWED_RUNTIMES.includes(staticConfig.runtime)) {
306757
- throw new Error(`Unsupported "runtime" property in \`config\`: ${JSON.stringify(staticConfig.runtime)} (must be one of: ${JSON.stringify(ALLOWED_RUNTIMES)})`);
306758
- }
306759
- if (staticConfig.runtime === 'experimental-edge') {
306760
- const name = config.zeroConfig
306761
- ? handler.substring(0, handler.length - 3)
306762
- : handler;
306763
- output = new build_utils_1.EdgeFunction({
306764
- entrypoint: handler,
306765
- files: preparedFiles,
306766
- // TODO: remove - these two properties should not be required
306767
- name,
306768
- deploymentTarget: 'v8-worker',
306769
- });
306754
+ const outputName = config.zeroConfig
306755
+ ? handler.substring(0, handler.length - 3)
306756
+ : handler;
306757
+ // Will output an `EdgeFunction` for when `config.middleware = true`
306758
+ // (i.e. for root-level "middleware" file) or if source code contains:
306759
+ // `export const config = { runtime: 'experimental-edge' }`
306760
+ let isEdgeFunction = false;
306761
+ // Add a catch-all `route` for Middleware
306762
+ if (config.middleware === true) {
306763
+ routes = [
306764
+ {
306765
+ src: '/.*',
306766
+ middlewarePath: config.zeroConfig
306767
+ ? outputName
306768
+ : path_1.relative(baseDir, entrypointPath),
306769
+ continue: true,
306770
+ },
306771
+ ];
306772
+ // Middleware is implicitly an Edge Function
306773
+ isEdgeFunction = true;
306774
+ }
306775
+ if (!isEdgeFunction) {
306776
+ const project = new ts_morph_1.Project();
306777
+ const staticConfig = static_config_1.getConfig(project, entrypointPath);
306778
+ if (staticConfig?.runtime) {
306779
+ if (!ALLOWED_RUNTIMES.includes(staticConfig.runtime)) {
306780
+ throw new Error(`Unsupported "runtime" property in \`config\`: ${JSON.stringify(staticConfig.runtime)} (must be one of: ${JSON.stringify(ALLOWED_RUNTIMES)})`);
306781
+ }
306782
+ isEdgeFunction = staticConfig.runtime === 'experimental-edge';
306770
306783
  }
306771
306784
  }
306772
- if (!output) {
306785
+ if (isEdgeFunction) {
306786
+ output = new build_utils_1.EdgeFunction({
306787
+ entrypoint: handler,
306788
+ files: preparedFiles,
306789
+ // TODO: remove - these two properties should not be required
306790
+ name: outputName,
306791
+ deploymentTarget: 'v8-worker',
306792
+ });
306793
+ }
306794
+ else {
306773
306795
  // "nodejs" runtime is the default
306774
306796
  const shouldAddHelpers = !(config.helpers === false || process.env.NODEJS_HELPERS === '0');
306775
306797
  output = new build_utils_1.NodejsLambda({
@@ -306781,7 +306803,7 @@ const build = async ({ files, entrypoint, workPath, repoRootPath, config = {}, m
306781
306803
  awsLambdaHandler,
306782
306804
  });
306783
306805
  }
306784
- return { output };
306806
+ return { routes, output };
306785
306807
  };
306786
306808
  exports.build = build;
306787
306809
  const prepareCache = ({ repoRootPath, workPath }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/node",
3
- "version": "2.1.0",
3
+ "version": "2.1.1-canary.2",
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.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": "0c7b54edad6adf48505abf2cbec01691b85963bb"
62
+ "gitHead": "b7b7923f92b370c5ef44bde3ced2dbc550f547e4"
60
63
  }