@vercel/node 2.2.1-canary.0 → 2.3.1
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/dist/dev-server.js +151 -50
- package/dist/index.js +490 -19
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +24 -0
- package/package.json +6 -4
package/dist/dev-server.js
CHANGED
@@ -68,8 +68,19 @@ const exit_hook_1 = __importDefault(require("exit-hook"));
|
|
68
68
|
const edge_runtime_1 = require("edge-runtime");
|
69
69
|
const static_config_1 = require("@vercel/static-config");
|
70
70
|
const ts_morph_1 = require("ts-morph");
|
71
|
-
const
|
71
|
+
const esbuild_1 = __importDefault(require("esbuild"));
|
72
72
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
73
|
+
const util_1 = require("util");
|
74
|
+
function logError(error) {
|
75
|
+
console.error(error.message);
|
76
|
+
if (error.stack) {
|
77
|
+
// only show the stack trace if debug is enabled
|
78
|
+
// because it points to internals, not user code
|
79
|
+
const errorPrefixLength = 'Error: '.length;
|
80
|
+
const errorMessageLength = errorPrefixLength + error.message.length;
|
81
|
+
build_utils_1.debug(error.stack.substring(errorMessageLength + 1));
|
82
|
+
}
|
83
|
+
}
|
73
84
|
function listen(server, port, host) {
|
74
85
|
return new Promise(resolve => {
|
75
86
|
server.listen(port, host, () => {
|
@@ -115,81 +126,158 @@ async function serializeRequest(message) {
|
|
115
126
|
body,
|
116
127
|
});
|
117
128
|
}
|
118
|
-
async function
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
129
|
+
async function compileUserCode(entrypoint) {
|
130
|
+
try {
|
131
|
+
const result = await esbuild_1.default.build({
|
132
|
+
platform: 'node',
|
133
|
+
target: 'node14',
|
134
|
+
sourcemap: 'inline',
|
135
|
+
bundle: true,
|
136
|
+
entryPoints: [entrypoint],
|
137
|
+
write: false,
|
138
|
+
format: 'cjs',
|
139
|
+
});
|
140
|
+
const compiledFile = result.outputFiles?.[0];
|
141
|
+
if (!compiledFile) {
|
142
|
+
throw new Error(`Compilation of ${entrypoint} produced no output files.`);
|
143
|
+
}
|
144
|
+
const userCode = new util_1.TextDecoder().decode(compiledFile.contents);
|
145
|
+
return `
|
146
|
+
${userCode};
|
123
147
|
|
124
|
-
|
125
|
-
|
126
|
-
|
148
|
+
addEventListener('fetch', async (event) => {
|
149
|
+
try {
|
150
|
+
let serializedRequest = await event.request.text();
|
151
|
+
let requestDetails = JSON.parse(serializedRequest);
|
127
152
|
|
128
|
-
|
153
|
+
let body;
|
129
154
|
|
130
|
-
|
131
|
-
|
132
|
-
|
155
|
+
if (requestDetails.method !== 'GET' && requestDetails.method !== 'HEAD') {
|
156
|
+
body = Uint8Array.from(atob(requestDetails.body), c => c.charCodeAt(0));
|
157
|
+
}
|
133
158
|
|
134
|
-
|
159
|
+
let requestUrl = requestDetails.headers['x-forwarded-proto'] + '://' + requestDetails.headers['x-forwarded-host'] + requestDetails.url;
|
135
160
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
161
|
+
let request = new Request(requestUrl, {
|
162
|
+
headers: requestDetails.headers,
|
163
|
+
method: requestDetails.method,
|
164
|
+
body: body
|
165
|
+
});
|
141
166
|
|
142
|
-
|
167
|
+
event.request = request;
|
143
168
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
169
|
+
let edgeHandler = module.exports.default;
|
170
|
+
if (!edgeHandler) {
|
171
|
+
throw new Error('No default export was found. Add a default export to handle requests.');
|
172
|
+
}
|
173
|
+
|
174
|
+
let response = await edgeHandler(event.request, event);
|
175
|
+
|
176
|
+
return event.respondWith(response);
|
177
|
+
} catch (error) {
|
178
|
+
// we can't easily show a meaningful stack trace
|
179
|
+
// so, stick to just the error message for now
|
180
|
+
event.respondWith(new Response(error.message, {
|
181
|
+
status: 500,
|
182
|
+
headers: {
|
183
|
+
'x-vercel-failed': 'edge-wrapper'
|
184
|
+
}
|
185
|
+
}));
|
186
|
+
}
|
187
|
+
})`;
|
188
|
+
}
|
189
|
+
catch (error) {
|
190
|
+
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
191
|
+
// So, stick with just the message for now.
|
192
|
+
console.error(`Failed to instantiate edge runtime.`);
|
193
|
+
logError(error);
|
194
|
+
return undefined;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
async function createEdgeRuntime(userCode) {
|
198
|
+
try {
|
199
|
+
if (!userCode) {
|
200
|
+
return undefined;
|
201
|
+
}
|
202
|
+
const edgeRuntime = new edge_runtime_1.EdgeRuntime({
|
203
|
+
initialCode: userCode,
|
204
|
+
extend: (context) => {
|
205
|
+
Object.assign(context, {
|
206
|
+
__dirname: '',
|
207
|
+
module: {
|
208
|
+
exports: {},
|
209
|
+
},
|
210
|
+
});
|
211
|
+
return context;
|
212
|
+
},
|
213
|
+
});
|
214
|
+
const server = await edge_runtime_1.runServer({ runtime: edgeRuntime });
|
215
|
+
exit_hook_1.default(server.close);
|
216
|
+
return server;
|
217
|
+
}
|
218
|
+
catch (error) {
|
219
|
+
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
220
|
+
// So, stick with just the message for now.
|
221
|
+
console.error('Failed to instantiate edge runtime.');
|
222
|
+
logError(error);
|
223
|
+
return undefined;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
async function createEdgeEventHandler(entrypoint) {
|
227
|
+
const userCode = await compileUserCode(entrypoint);
|
228
|
+
const server = await createEdgeRuntime(userCode);
|
162
229
|
return async function (request) {
|
230
|
+
if (!server) {
|
231
|
+
// this error state is already logged, but we have to wait until here to exit the process
|
232
|
+
// this matches the serverless function bridge launcher's behavior when
|
233
|
+
// an error is thrown in the function
|
234
|
+
process.exit(1);
|
235
|
+
}
|
163
236
|
const response = await node_fetch_1.default(server.url, {
|
237
|
+
redirect: 'manual',
|
164
238
|
method: 'post',
|
165
239
|
body: await serializeRequest(request),
|
166
240
|
});
|
241
|
+
const body = await response.text();
|
242
|
+
const isUserError = response.headers.get('x-vercel-failed') === 'edge-wrapper';
|
243
|
+
if (isUserError && response.status >= 500) {
|
244
|
+
// this error was "unhandled" from the user code's perspective
|
245
|
+
console.log(`Unhandled rejection: ${body}`);
|
246
|
+
// this matches the serverless function bridge launcher's behavior when
|
247
|
+
// an error is thrown in the function
|
248
|
+
process.exit(1);
|
249
|
+
}
|
167
250
|
return {
|
168
251
|
statusCode: response.status,
|
169
252
|
headers: response.headers.raw(),
|
170
|
-
body
|
253
|
+
body,
|
171
254
|
encoding: 'utf8',
|
172
255
|
};
|
173
256
|
};
|
174
257
|
}
|
175
258
|
const validRuntimes = ['experimental-edge'];
|
176
|
-
function parseRuntime(entrypoint) {
|
259
|
+
function parseRuntime(entrypoint, entryPointPath) {
|
177
260
|
const project = new ts_morph_1.Project();
|
178
|
-
const staticConfig = static_config_1.getConfig(project,
|
261
|
+
const staticConfig = static_config_1.getConfig(project, entryPointPath);
|
179
262
|
const runtime = staticConfig?.runtime;
|
180
263
|
if (runtime && !validRuntimes.includes(runtime)) {
|
181
|
-
throw new Error(`Invalid function runtime for "${entrypoint}": ${
|
264
|
+
throw new Error(`Invalid function runtime "${runtime}" for "${entrypoint}". Valid runtimes are: ${JSON.stringify(validRuntimes)}`);
|
182
265
|
}
|
183
266
|
return runtime;
|
184
267
|
}
|
185
|
-
async function createEventHandler(entrypoint, options) {
|
186
|
-
const
|
187
|
-
|
188
|
-
|
268
|
+
async function createEventHandler(entrypoint, config, options) {
|
269
|
+
const entryPointPath = path_1.join(process.cwd(), entrypoint);
|
270
|
+
const runtime = parseRuntime(entrypoint, entryPointPath);
|
271
|
+
// `middleware.js`/`middleware.ts` file is always run as
|
272
|
+
// an Edge Function, otherwise needs to be opted-in via
|
273
|
+
// `export const config = { runtime: 'experimental-edge' }`
|
274
|
+
if (config.middleware === true || runtime === 'experimental-edge') {
|
275
|
+
return createEdgeEventHandler(entryPointPath);
|
189
276
|
}
|
190
|
-
return createServerlessEventHandler(
|
277
|
+
return createServerlessEventHandler(entryPointPath, options);
|
191
278
|
}
|
192
279
|
let handleEvent;
|
280
|
+
let handlerEventError;
|
193
281
|
async function main() {
|
194
282
|
const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || '{}');
|
195
283
|
delete process.env.VERCEL_DEV_CONFIG;
|
@@ -198,8 +286,15 @@ async function main() {
|
|
198
286
|
const shouldAddHelpers = !(config.helpers === false || buildEnv.NODEJS_HELPERS === '0');
|
199
287
|
const proxyServer = http_1.createServer(onDevRequest);
|
200
288
|
await listen(proxyServer, 0, '127.0.0.1');
|
201
|
-
|
202
|
-
|
289
|
+
try {
|
290
|
+
handleEvent = await createEventHandler(entrypoint, config, {
|
291
|
+
shouldAddHelpers,
|
292
|
+
});
|
293
|
+
}
|
294
|
+
catch (error) {
|
295
|
+
logError(error);
|
296
|
+
handlerEventError = error;
|
297
|
+
}
|
203
298
|
const address = proxyServer.address();
|
204
299
|
if (typeof process.send === 'function') {
|
205
300
|
process.send(address);
|
@@ -224,6 +319,12 @@ function rawBody(readable) {
|
|
224
319
|
}
|
225
320
|
exports.rawBody = rawBody;
|
226
321
|
async function onDevRequest(req, res) {
|
322
|
+
if (handlerEventError) {
|
323
|
+
// this error state is already logged, but we have to wait until here to exit the process
|
324
|
+
// this matches the serverless function bridge launcher's behavior when
|
325
|
+
// an error is thrown in the function
|
326
|
+
process.exit(1);
|
327
|
+
}
|
227
328
|
if (!handleEvent) {
|
228
329
|
res.statusCode = 500;
|
229
330
|
res.end('Bridge is not ready, please try again');
|
@@ -259,6 +360,6 @@ function fixConfigDev(config) {
|
|
259
360
|
}
|
260
361
|
exports.fixConfigDev = fixConfigDev;
|
261
362
|
main().catch(err => {
|
262
|
-
|
363
|
+
logError(err);
|
263
364
|
process.exit(1);
|
264
365
|
});
|
package/dist/index.js
CHANGED
@@ -296058,6 +296058,423 @@ module.exports = {
|
|
296058
296058
|
}
|
296059
296059
|
|
296060
296060
|
|
296061
|
+
/***/ }),
|
296062
|
+
|
296063
|
+
/***/ 91786:
|
296064
|
+
/***/ ((__unused_webpack_module, exports) => {
|
296065
|
+
|
296066
|
+
"use strict";
|
296067
|
+
|
296068
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
296069
|
+
exports.pathToRegexp = exports.tokensToRegexp = exports.regexpToFunction = exports.match = exports.tokensToFunction = exports.compile = exports.parse = void 0;
|
296070
|
+
/**
|
296071
|
+
* Tokenize input string.
|
296072
|
+
*/
|
296073
|
+
function lexer(str) {
|
296074
|
+
var tokens = [];
|
296075
|
+
var i = 0;
|
296076
|
+
while (i < str.length) {
|
296077
|
+
var char = str[i];
|
296078
|
+
if (char === "*" || char === "+" || char === "?") {
|
296079
|
+
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
|
296080
|
+
continue;
|
296081
|
+
}
|
296082
|
+
if (char === "\\") {
|
296083
|
+
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
|
296084
|
+
continue;
|
296085
|
+
}
|
296086
|
+
if (char === "{") {
|
296087
|
+
tokens.push({ type: "OPEN", index: i, value: str[i++] });
|
296088
|
+
continue;
|
296089
|
+
}
|
296090
|
+
if (char === "}") {
|
296091
|
+
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
|
296092
|
+
continue;
|
296093
|
+
}
|
296094
|
+
if (char === ":") {
|
296095
|
+
var name = "";
|
296096
|
+
var j = i + 1;
|
296097
|
+
while (j < str.length) {
|
296098
|
+
var code = str.charCodeAt(j);
|
296099
|
+
if (
|
296100
|
+
// `0-9`
|
296101
|
+
(code >= 48 && code <= 57) ||
|
296102
|
+
// `A-Z`
|
296103
|
+
(code >= 65 && code <= 90) ||
|
296104
|
+
// `a-z`
|
296105
|
+
(code >= 97 && code <= 122) ||
|
296106
|
+
// `_`
|
296107
|
+
code === 95) {
|
296108
|
+
name += str[j++];
|
296109
|
+
continue;
|
296110
|
+
}
|
296111
|
+
break;
|
296112
|
+
}
|
296113
|
+
if (!name)
|
296114
|
+
throw new TypeError("Missing parameter name at ".concat(i));
|
296115
|
+
tokens.push({ type: "NAME", index: i, value: name });
|
296116
|
+
i = j;
|
296117
|
+
continue;
|
296118
|
+
}
|
296119
|
+
if (char === "(") {
|
296120
|
+
var count = 1;
|
296121
|
+
var pattern = "";
|
296122
|
+
var j = i + 1;
|
296123
|
+
if (str[j] === "?") {
|
296124
|
+
throw new TypeError("Pattern cannot start with \"?\" at ".concat(j));
|
296125
|
+
}
|
296126
|
+
while (j < str.length) {
|
296127
|
+
if (str[j] === "\\") {
|
296128
|
+
pattern += str[j++] + str[j++];
|
296129
|
+
continue;
|
296130
|
+
}
|
296131
|
+
if (str[j] === ")") {
|
296132
|
+
count--;
|
296133
|
+
if (count === 0) {
|
296134
|
+
j++;
|
296135
|
+
break;
|
296136
|
+
}
|
296137
|
+
}
|
296138
|
+
else if (str[j] === "(") {
|
296139
|
+
count++;
|
296140
|
+
if (str[j + 1] !== "?") {
|
296141
|
+
throw new TypeError("Capturing groups are not allowed at ".concat(j));
|
296142
|
+
}
|
296143
|
+
}
|
296144
|
+
pattern += str[j++];
|
296145
|
+
}
|
296146
|
+
if (count)
|
296147
|
+
throw new TypeError("Unbalanced pattern at ".concat(i));
|
296148
|
+
if (!pattern)
|
296149
|
+
throw new TypeError("Missing pattern at ".concat(i));
|
296150
|
+
tokens.push({ type: "PATTERN", index: i, value: pattern });
|
296151
|
+
i = j;
|
296152
|
+
continue;
|
296153
|
+
}
|
296154
|
+
tokens.push({ type: "CHAR", index: i, value: str[i++] });
|
296155
|
+
}
|
296156
|
+
tokens.push({ type: "END", index: i, value: "" });
|
296157
|
+
return tokens;
|
296158
|
+
}
|
296159
|
+
/**
|
296160
|
+
* Parse a string for the raw tokens.
|
296161
|
+
*/
|
296162
|
+
function parse(str, options) {
|
296163
|
+
if (options === void 0) { options = {}; }
|
296164
|
+
var tokens = lexer(str);
|
296165
|
+
var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
|
296166
|
+
var defaultPattern = "[^".concat(escapeString(options.delimiter || "/#?"), "]+?");
|
296167
|
+
var result = [];
|
296168
|
+
var key = 0;
|
296169
|
+
var i = 0;
|
296170
|
+
var path = "";
|
296171
|
+
var tryConsume = function (type) {
|
296172
|
+
if (i < tokens.length && tokens[i].type === type)
|
296173
|
+
return tokens[i++].value;
|
296174
|
+
};
|
296175
|
+
var mustConsume = function (type) {
|
296176
|
+
var value = tryConsume(type);
|
296177
|
+
if (value !== undefined)
|
296178
|
+
return value;
|
296179
|
+
var _a = tokens[i], nextType = _a.type, index = _a.index;
|
296180
|
+
throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type));
|
296181
|
+
};
|
296182
|
+
var consumeText = function () {
|
296183
|
+
var result = "";
|
296184
|
+
var value;
|
296185
|
+
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
|
296186
|
+
result += value;
|
296187
|
+
}
|
296188
|
+
return result;
|
296189
|
+
};
|
296190
|
+
while (i < tokens.length) {
|
296191
|
+
var char = tryConsume("CHAR");
|
296192
|
+
var name = tryConsume("NAME");
|
296193
|
+
var pattern = tryConsume("PATTERN");
|
296194
|
+
if (name || pattern) {
|
296195
|
+
var prefix = char || "";
|
296196
|
+
if (prefixes.indexOf(prefix) === -1) {
|
296197
|
+
path += prefix;
|
296198
|
+
prefix = "";
|
296199
|
+
}
|
296200
|
+
if (path) {
|
296201
|
+
result.push(path);
|
296202
|
+
path = "";
|
296203
|
+
}
|
296204
|
+
result.push({
|
296205
|
+
name: name || key++,
|
296206
|
+
prefix: prefix,
|
296207
|
+
suffix: "",
|
296208
|
+
pattern: pattern || defaultPattern,
|
296209
|
+
modifier: tryConsume("MODIFIER") || "",
|
296210
|
+
});
|
296211
|
+
continue;
|
296212
|
+
}
|
296213
|
+
var value = char || tryConsume("ESCAPED_CHAR");
|
296214
|
+
if (value) {
|
296215
|
+
path += value;
|
296216
|
+
continue;
|
296217
|
+
}
|
296218
|
+
if (path) {
|
296219
|
+
result.push(path);
|
296220
|
+
path = "";
|
296221
|
+
}
|
296222
|
+
var open = tryConsume("OPEN");
|
296223
|
+
if (open) {
|
296224
|
+
var prefix = consumeText();
|
296225
|
+
var name_1 = tryConsume("NAME") || "";
|
296226
|
+
var pattern_1 = tryConsume("PATTERN") || "";
|
296227
|
+
var suffix = consumeText();
|
296228
|
+
mustConsume("CLOSE");
|
296229
|
+
result.push({
|
296230
|
+
name: name_1 || (pattern_1 ? key++ : ""),
|
296231
|
+
pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
|
296232
|
+
prefix: prefix,
|
296233
|
+
suffix: suffix,
|
296234
|
+
modifier: tryConsume("MODIFIER") || "",
|
296235
|
+
});
|
296236
|
+
continue;
|
296237
|
+
}
|
296238
|
+
mustConsume("END");
|
296239
|
+
}
|
296240
|
+
return result;
|
296241
|
+
}
|
296242
|
+
exports.parse = parse;
|
296243
|
+
/**
|
296244
|
+
* Compile a string to a template function for the path.
|
296245
|
+
*/
|
296246
|
+
function compile(str, options) {
|
296247
|
+
return tokensToFunction(parse(str, options), options);
|
296248
|
+
}
|
296249
|
+
exports.compile = compile;
|
296250
|
+
/**
|
296251
|
+
* Expose a method for transforming tokens into the path function.
|
296252
|
+
*/
|
296253
|
+
function tokensToFunction(tokens, options) {
|
296254
|
+
if (options === void 0) { options = {}; }
|
296255
|
+
var reFlags = flags(options);
|
296256
|
+
var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b;
|
296257
|
+
// Compile all the tokens into regexps.
|
296258
|
+
var matches = tokens.map(function (token) {
|
296259
|
+
if (typeof token === "object") {
|
296260
|
+
return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags);
|
296261
|
+
}
|
296262
|
+
});
|
296263
|
+
return function (data) {
|
296264
|
+
var path = "";
|
296265
|
+
for (var i = 0; i < tokens.length; i++) {
|
296266
|
+
var token = tokens[i];
|
296267
|
+
if (typeof token === "string") {
|
296268
|
+
path += token;
|
296269
|
+
continue;
|
296270
|
+
}
|
296271
|
+
var value = data ? data[token.name] : undefined;
|
296272
|
+
var optional = token.modifier === "?" || token.modifier === "*";
|
296273
|
+
var repeat = token.modifier === "*" || token.modifier === "+";
|
296274
|
+
if (Array.isArray(value)) {
|
296275
|
+
if (!repeat) {
|
296276
|
+
throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array"));
|
296277
|
+
}
|
296278
|
+
if (value.length === 0) {
|
296279
|
+
if (optional)
|
296280
|
+
continue;
|
296281
|
+
throw new TypeError("Expected \"".concat(token.name, "\" to not be empty"));
|
296282
|
+
}
|
296283
|
+
for (var j = 0; j < value.length; j++) {
|
296284
|
+
var segment = encode(value[j], token);
|
296285
|
+
if (validate && !matches[i].test(segment)) {
|
296286
|
+
throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
296287
|
+
}
|
296288
|
+
path += token.prefix + segment + token.suffix;
|
296289
|
+
}
|
296290
|
+
continue;
|
296291
|
+
}
|
296292
|
+
if (typeof value === "string" || typeof value === "number") {
|
296293
|
+
var segment = encode(String(value), token);
|
296294
|
+
if (validate && !matches[i].test(segment)) {
|
296295
|
+
throw new TypeError("Expected \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
296296
|
+
}
|
296297
|
+
path += token.prefix + segment + token.suffix;
|
296298
|
+
continue;
|
296299
|
+
}
|
296300
|
+
if (optional)
|
296301
|
+
continue;
|
296302
|
+
var typeOfMessage = repeat ? "an array" : "a string";
|
296303
|
+
throw new TypeError("Expected \"".concat(token.name, "\" to be ").concat(typeOfMessage));
|
296304
|
+
}
|
296305
|
+
return path;
|
296306
|
+
};
|
296307
|
+
}
|
296308
|
+
exports.tokensToFunction = tokensToFunction;
|
296309
|
+
/**
|
296310
|
+
* Create path match function from `path-to-regexp` spec.
|
296311
|
+
*/
|
296312
|
+
function match(str, options) {
|
296313
|
+
var keys = [];
|
296314
|
+
var re = pathToRegexp(str, keys, options);
|
296315
|
+
return regexpToFunction(re, keys, options);
|
296316
|
+
}
|
296317
|
+
exports.match = match;
|
296318
|
+
/**
|
296319
|
+
* Create a path match function from `path-to-regexp` output.
|
296320
|
+
*/
|
296321
|
+
function regexpToFunction(re, keys, options) {
|
296322
|
+
if (options === void 0) { options = {}; }
|
296323
|
+
var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a;
|
296324
|
+
return function (pathname) {
|
296325
|
+
var m = re.exec(pathname);
|
296326
|
+
if (!m)
|
296327
|
+
return false;
|
296328
|
+
var path = m[0], index = m.index;
|
296329
|
+
var params = Object.create(null);
|
296330
|
+
var _loop_1 = function (i) {
|
296331
|
+
if (m[i] === undefined)
|
296332
|
+
return "continue";
|
296333
|
+
var key = keys[i - 1];
|
296334
|
+
if (key.modifier === "*" || key.modifier === "+") {
|
296335
|
+
params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) {
|
296336
|
+
return decode(value, key);
|
296337
|
+
});
|
296338
|
+
}
|
296339
|
+
else {
|
296340
|
+
params[key.name] = decode(m[i], key);
|
296341
|
+
}
|
296342
|
+
};
|
296343
|
+
for (var i = 1; i < m.length; i++) {
|
296344
|
+
_loop_1(i);
|
296345
|
+
}
|
296346
|
+
return { path: path, index: index, params: params };
|
296347
|
+
};
|
296348
|
+
}
|
296349
|
+
exports.regexpToFunction = regexpToFunction;
|
296350
|
+
/**
|
296351
|
+
* Escape a regular expression string.
|
296352
|
+
*/
|
296353
|
+
function escapeString(str) {
|
296354
|
+
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
296355
|
+
}
|
296356
|
+
/**
|
296357
|
+
* Get the flags for a regexp from the options.
|
296358
|
+
*/
|
296359
|
+
function flags(options) {
|
296360
|
+
return options && options.sensitive ? "" : "i";
|
296361
|
+
}
|
296362
|
+
/**
|
296363
|
+
* Pull out keys from a regexp.
|
296364
|
+
*/
|
296365
|
+
function regexpToRegexp(path, keys) {
|
296366
|
+
if (!keys)
|
296367
|
+
return path;
|
296368
|
+
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
|
296369
|
+
var index = 0;
|
296370
|
+
var execResult = groupsRegex.exec(path.source);
|
296371
|
+
while (execResult) {
|
296372
|
+
keys.push({
|
296373
|
+
// Use parenthesized substring match if available, index otherwise
|
296374
|
+
name: execResult[1] || index++,
|
296375
|
+
prefix: "",
|
296376
|
+
suffix: "",
|
296377
|
+
modifier: "",
|
296378
|
+
pattern: "",
|
296379
|
+
});
|
296380
|
+
execResult = groupsRegex.exec(path.source);
|
296381
|
+
}
|
296382
|
+
return path;
|
296383
|
+
}
|
296384
|
+
/**
|
296385
|
+
* Transform an array into a regexp.
|
296386
|
+
*/
|
296387
|
+
function arrayToRegexp(paths, keys, options) {
|
296388
|
+
var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; });
|
296389
|
+
return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options));
|
296390
|
+
}
|
296391
|
+
/**
|
296392
|
+
* Create a path regexp from string input.
|
296393
|
+
*/
|
296394
|
+
function stringToRegexp(path, keys, options) {
|
296395
|
+
return tokensToRegexp(parse(path, options), keys, options);
|
296396
|
+
}
|
296397
|
+
/**
|
296398
|
+
* Expose a function for taking tokens and returning a RegExp.
|
296399
|
+
*/
|
296400
|
+
function tokensToRegexp(tokens, keys, options) {
|
296401
|
+
if (options === void 0) { options = {}; }
|
296402
|
+
var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f;
|
296403
|
+
var endsWithRe = "[".concat(escapeString(endsWith), "]|$");
|
296404
|
+
var delimiterRe = "[".concat(escapeString(delimiter), "]");
|
296405
|
+
var route = start ? "^" : "";
|
296406
|
+
// Iterate over the tokens and create our regexp string.
|
296407
|
+
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
|
296408
|
+
var token = tokens_1[_i];
|
296409
|
+
if (typeof token === "string") {
|
296410
|
+
route += escapeString(encode(token));
|
296411
|
+
}
|
296412
|
+
else {
|
296413
|
+
var prefix = escapeString(encode(token.prefix));
|
296414
|
+
var suffix = escapeString(encode(token.suffix));
|
296415
|
+
if (token.pattern) {
|
296416
|
+
if (keys)
|
296417
|
+
keys.push(token);
|
296418
|
+
if (prefix || suffix) {
|
296419
|
+
if (token.modifier === "+" || token.modifier === "*") {
|
296420
|
+
var mod = token.modifier === "*" ? "?" : "";
|
296421
|
+
route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod);
|
296422
|
+
}
|
296423
|
+
else {
|
296424
|
+
route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier);
|
296425
|
+
}
|
296426
|
+
}
|
296427
|
+
else {
|
296428
|
+
if (token.modifier === "+" || token.modifier === "*") {
|
296429
|
+
route += "((?:".concat(token.pattern, ")").concat(token.modifier, ")");
|
296430
|
+
}
|
296431
|
+
else {
|
296432
|
+
route += "(".concat(token.pattern, ")").concat(token.modifier);
|
296433
|
+
}
|
296434
|
+
}
|
296435
|
+
}
|
296436
|
+
else {
|
296437
|
+
route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier);
|
296438
|
+
}
|
296439
|
+
}
|
296440
|
+
}
|
296441
|
+
if (end) {
|
296442
|
+
if (!strict)
|
296443
|
+
route += "".concat(delimiterRe, "?");
|
296444
|
+
route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")");
|
296445
|
+
}
|
296446
|
+
else {
|
296447
|
+
var endToken = tokens[tokens.length - 1];
|
296448
|
+
var isEndDelimited = typeof endToken === "string"
|
296449
|
+
? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1
|
296450
|
+
: endToken === undefined;
|
296451
|
+
if (!strict) {
|
296452
|
+
route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?");
|
296453
|
+
}
|
296454
|
+
if (!isEndDelimited) {
|
296455
|
+
route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")");
|
296456
|
+
}
|
296457
|
+
}
|
296458
|
+
return new RegExp(route, flags(options));
|
296459
|
+
}
|
296460
|
+
exports.tokensToRegexp = tokensToRegexp;
|
296461
|
+
/**
|
296462
|
+
* Normalize the given path string, returning a regular expression.
|
296463
|
+
*
|
296464
|
+
* An empty array can be passed in for the keys, which will hold the
|
296465
|
+
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
296466
|
+
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
296467
|
+
*/
|
296468
|
+
function pathToRegexp(path, keys, options) {
|
296469
|
+
if (path instanceof RegExp)
|
296470
|
+
return regexpToRegexp(path, keys);
|
296471
|
+
if (Array.isArray(path))
|
296472
|
+
return arrayToRegexp(path, keys, options);
|
296473
|
+
return stringToRegexp(path, keys, options);
|
296474
|
+
}
|
296475
|
+
exports.pathToRegexp = pathToRegexp;
|
296476
|
+
//# sourceMappingURL=index.js.map
|
296477
|
+
|
296061
296478
|
/***/ }),
|
296062
296479
|
|
296063
296480
|
/***/ 92879:
|
@@ -306526,6 +306943,7 @@ const build_utils_1 = __webpack_require__(63445);
|
|
306526
306943
|
Object.defineProperty(exports, "shouldServe", ({ enumerable: true, get: function () { return build_utils_1.shouldServe; } }));
|
306527
306944
|
const static_config_1 = __webpack_require__(76849);
|
306528
306945
|
const typescript_1 = __webpack_require__(80774);
|
306946
|
+
const utils_1 = __webpack_require__(84411);
|
306529
306947
|
function isPortInfo(v) {
|
306530
306948
|
return v && typeof v.port === 'number';
|
306531
306949
|
}
|
@@ -306754,33 +307172,37 @@ const build = async ({ files, entrypoint, workPath, repoRootPath, config = {}, m
|
|
306754
307172
|
const outputName = config.zeroConfig
|
306755
307173
|
? handler.substring(0, handler.length - 3)
|
306756
307174
|
: handler;
|
307175
|
+
const isMiddleware = config.middleware === true;
|
306757
307176
|
// Will output an `EdgeFunction` for when `config.middleware = true`
|
306758
307177
|
// (i.e. for root-level "middleware" file) or if source code contains:
|
306759
307178
|
// `export const config = { runtime: 'experimental-edge' }`
|
306760
|
-
let isEdgeFunction =
|
306761
|
-
|
306762
|
-
|
307179
|
+
let isEdgeFunction = isMiddleware;
|
307180
|
+
const project = new ts_morph_1.Project();
|
307181
|
+
const staticConfig = static_config_1.getConfig(project, entrypointPath);
|
307182
|
+
if (staticConfig?.runtime) {
|
307183
|
+
if (!ALLOWED_RUNTIMES.includes(staticConfig.runtime)) {
|
307184
|
+
throw new Error(`Unsupported "runtime" property in \`config\`: ${JSON.stringify(staticConfig.runtime)} (must be one of: ${JSON.stringify(ALLOWED_RUNTIMES)})`);
|
307185
|
+
}
|
307186
|
+
isEdgeFunction = staticConfig.runtime === 'experimental-edge';
|
307187
|
+
}
|
307188
|
+
// Add a `route` for Middleware
|
307189
|
+
if (isMiddleware) {
|
307190
|
+
if (!isEdgeFunction) {
|
307191
|
+
// Root-level middleware file can not have `export const config = { runtime: 'nodejs' }`
|
307192
|
+
throw new Error(`Middleware file can not be a Node.js Serverless Function`);
|
307193
|
+
}
|
307194
|
+
// Middleware is a catch-all for all paths unless a `matcher` property is defined
|
307195
|
+
const src = utils_1.getRegExpFromMatchers(staticConfig?.matcher);
|
306763
307196
|
routes = [
|
306764
307197
|
{
|
306765
|
-
src
|
307198
|
+
src,
|
306766
307199
|
middlewarePath: config.zeroConfig
|
306767
307200
|
? outputName
|
306768
307201
|
: path_1.relative(baseDir, entrypointPath),
|
306769
307202
|
continue: true,
|
307203
|
+
override: true,
|
306770
307204
|
},
|
306771
307205
|
];
|
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';
|
306783
|
-
}
|
306784
307206
|
}
|
306785
307207
|
if (isEdgeFunction) {
|
306786
307208
|
output = new build_utils_1.EdgeFunction({
|
@@ -306812,7 +307234,21 @@ const prepareCache = ({ repoRootPath, workPath }) => {
|
|
306812
307234
|
exports.prepareCache = prepareCache;
|
306813
307235
|
const startDevServer = async (opts) => {
|
306814
307236
|
const { entrypoint, workPath, config, meta = {} } = opts;
|
306815
|
-
const
|
307237
|
+
const entrypointPath = path_1.join(workPath, entrypoint);
|
307238
|
+
if (config.middleware === true && typeof meta.requestUrl === 'string') {
|
307239
|
+
// TODO: static config is also parsed in `dev-server.ts`.
|
307240
|
+
// we should pass in this version as an env var instead.
|
307241
|
+
const project = new ts_morph_1.Project();
|
307242
|
+
const staticConfig = static_config_1.getConfig(project, entrypointPath);
|
307243
|
+
// Middleware is a catch-all for all paths unless a `matcher` property is defined
|
307244
|
+
const matchers = new RegExp(utils_1.getRegExpFromMatchers(staticConfig?.matcher));
|
307245
|
+
if (!matchers.test(meta.requestUrl)) {
|
307246
|
+
// If the "matchers" doesn't say to handle this
|
307247
|
+
// path then skip middleware invocation
|
307248
|
+
return null;
|
307249
|
+
}
|
307250
|
+
}
|
307251
|
+
const entryDir = path_1.dirname(entrypointPath);
|
306816
307252
|
const projectTsConfig = await build_utils_1.walkParentDirs({
|
306817
307253
|
base: workPath,
|
306818
307254
|
start: entryDir,
|
@@ -306841,6 +307277,9 @@ const startDevServer = async (opts) => {
|
|
306841
307277
|
},
|
306842
307278
|
});
|
306843
307279
|
const { pid } = child;
|
307280
|
+
if (!pid) {
|
307281
|
+
throw new Error(`Child Process has no "pid" when forking: "${devServerPath}"`);
|
307282
|
+
}
|
306844
307283
|
const onMessage = once_1.default(child, 'message');
|
306845
307284
|
const onExit = once_1.default.spread(child, 'exit');
|
306846
307285
|
const result = await Promise.race([onMessage, onExit]);
|
@@ -306862,12 +307301,12 @@ const startDevServer = async (opts) => {
|
|
306862
307301
|
// Got "exit" event from child process
|
306863
307302
|
const [exitCode, signal] = result;
|
306864
307303
|
const reason = signal ? `"${signal}" signal` : `exit code ${exitCode}`;
|
306865
|
-
throw new Error(
|
307304
|
+
throw new Error(`Function \`${entrypoint}\` failed with ${reason}`);
|
306866
307305
|
}
|
306867
307306
|
};
|
306868
307307
|
exports.startDevServer = startDevServer;
|
306869
307308
|
async function doTypeCheck({ entrypoint, workPath, meta = {} }, projectTsConfig) {
|
306870
|
-
const { devCacheDir = path_1.join(workPath, '.
|
307309
|
+
const { devCacheDir = path_1.join(workPath, '.vercel', 'cache') } = meta;
|
306871
307310
|
const entrypointCacheDir = path_1.join(devCacheDir, 'node', entrypoint);
|
306872
307311
|
// In order to type-check a single file, a standalone tsconfig
|
306873
307312
|
// file needs to be created that inherits from the base one :(
|
@@ -307283,6 +307722,38 @@ function filterDiagnostics(diagnostics, ignore) {
|
|
307283
307722
|
}
|
307284
307723
|
|
307285
307724
|
|
307725
|
+
/***/ }),
|
307726
|
+
|
307727
|
+
/***/ 84411:
|
307728
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
307729
|
+
|
307730
|
+
"use strict";
|
307731
|
+
|
307732
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
307733
|
+
exports.getRegExpFromMatchers = void 0;
|
307734
|
+
const path_to_regexp_1 = __webpack_require__(91786);
|
307735
|
+
function getRegExpFromMatchers(matcherOrMatchers) {
|
307736
|
+
if (!matcherOrMatchers) {
|
307737
|
+
return '^/.*$';
|
307738
|
+
}
|
307739
|
+
const matchers = Array.isArray(matcherOrMatchers)
|
307740
|
+
? matcherOrMatchers
|
307741
|
+
: [matcherOrMatchers];
|
307742
|
+
return matchers.map(getRegExpFromMatcher).join('|');
|
307743
|
+
}
|
307744
|
+
exports.getRegExpFromMatchers = getRegExpFromMatchers;
|
307745
|
+
function getRegExpFromMatcher(matcher) {
|
307746
|
+
if (typeof matcher !== 'string') {
|
307747
|
+
throw new Error('`matcher` must be a path matcher or an array of path matchers');
|
307748
|
+
}
|
307749
|
+
if (!matcher.startsWith('/')) {
|
307750
|
+
throw new Error('`matcher`: path matcher must start with /');
|
307751
|
+
}
|
307752
|
+
const re = path_to_regexp_1.pathToRegexp(matcher);
|
307753
|
+
return re.source;
|
307754
|
+
}
|
307755
|
+
|
307756
|
+
|
307286
307757
|
/***/ }),
|
307287
307758
|
|
307288
307759
|
/***/ 80918:
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export declare function getRegExpFromMatchers(matcherOrMatchers: unknown): string;
|
package/dist/utils.js
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getRegExpFromMatchers = void 0;
|
4
|
+
const path_to_regexp_1 = require("path-to-regexp");
|
5
|
+
function getRegExpFromMatchers(matcherOrMatchers) {
|
6
|
+
if (!matcherOrMatchers) {
|
7
|
+
return '^/.*$';
|
8
|
+
}
|
9
|
+
const matchers = Array.isArray(matcherOrMatchers)
|
10
|
+
? matcherOrMatchers
|
11
|
+
: [matcherOrMatchers];
|
12
|
+
return matchers.map(getRegExpFromMatcher).join('|');
|
13
|
+
}
|
14
|
+
exports.getRegExpFromMatchers = getRegExpFromMatchers;
|
15
|
+
function getRegExpFromMatcher(matcher) {
|
16
|
+
if (typeof matcher !== 'string') {
|
17
|
+
throw new Error('`matcher` must be a path matcher or an array of path matchers');
|
18
|
+
}
|
19
|
+
if (!matcher.startsWith('/')) {
|
20
|
+
throw new Error('`matcher`: path matcher must start with /');
|
21
|
+
}
|
22
|
+
const re = path_to_regexp_1.pathToRegexp(matcher);
|
23
|
+
return re.source;
|
24
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/node",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.3.1",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "./dist/index",
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
@@ -31,11 +31,11 @@
|
|
31
31
|
},
|
32
32
|
"dependencies": {
|
33
33
|
"@types/node": "*",
|
34
|
-
"@vercel/build-utils": "4.
|
35
|
-
"@vercel/ncc": "0.24.0",
|
34
|
+
"@vercel/build-utils": "4.2.0",
|
36
35
|
"@vercel/node-bridge": "3.0.0",
|
37
36
|
"@vercel/static-config": "2.0.1",
|
38
37
|
"edge-runtime": "1.0.1",
|
38
|
+
"esbuild": "0.14.47",
|
39
39
|
"exit-hook": "2.2.1",
|
40
40
|
"node-fetch": "2.6.1",
|
41
41
|
"ts-node": "8.9.1",
|
@@ -52,12 +52,14 @@
|
|
52
52
|
"@types/jest": "27.4.1",
|
53
53
|
"@types/node-fetch": "^2.6.1",
|
54
54
|
"@types/test-listen": "1.1.0",
|
55
|
+
"@vercel/ncc": "0.24.0",
|
55
56
|
"@vercel/nft": "0.19.1",
|
56
57
|
"content-type": "1.0.4",
|
57
58
|
"cookie": "0.4.0",
|
58
59
|
"etag": "1.8.1",
|
60
|
+
"path-to-regexp": "6.2.1",
|
59
61
|
"source-map-support": "0.5.12",
|
60
62
|
"test-listen": "1.1.0"
|
61
63
|
},
|
62
|
-
"gitHead": "
|
64
|
+
"gitHead": "b399fe7037eb3e4c42167ba28e82c9ce0332f7a0"
|
63
65
|
}
|