vercel 54.15.0 → 54.16.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/dist/chunks/{add-6XHROCMP.js → add-ODBKI7EV.js} +5 -5
- package/dist/chunks/{chunk-AWD3IGXU.js → chunk-3NR6OYDV.js} +1 -1
- package/dist/chunks/{chunk-OQD4G5FW.js → chunk-76QQSALN.js} +3 -3
- package/dist/chunks/{chunk-3RIVJWW5.js → chunk-7CTLNKAS.js} +48 -9
- package/dist/chunks/{chunk-OEYKL4IY.js → chunk-BGQPLZFA.js} +6 -6
- package/dist/chunks/{chunk-DCN3SOR6.js → chunk-BIHRICRM.js} +2 -2
- package/dist/chunks/{chunk-6SL223IW.js → chunk-FBYYZKN3.js} +4 -1
- package/dist/chunks/{chunk-TLVKY7WL.js → chunk-HL5ZRVF2.js} +6 -6
- package/dist/chunks/{chunk-WGH26RJV.js → chunk-HXAMK45D.js} +2 -2
- package/dist/chunks/{chunk-SFPJ3VR7.js → chunk-INFYZRHS.js} +286 -76
- package/dist/chunks/{chunk-PMUUPCDL.js → chunk-JFA4NUXP.js} +1 -1
- package/dist/chunks/{chunk-LABX5FSJ.js → chunk-KJMSI2CT.js} +1 -1
- package/dist/chunks/{chunk-EAEEBPMD.js → chunk-LJXYGWOY.js} +11 -3
- package/dist/chunks/{chunk-AG6TBL6C.js → chunk-MSWXRAHA.js} +1 -1
- package/dist/chunks/{chunk-HSXUEJ4T.js → chunk-NVITPK2U.js} +1 -1
- package/dist/chunks/{chunk-RHXSECUF.js → chunk-O6YJBWWC.js} +1 -1
- package/dist/chunks/{chunk-LOPPFUV3.js → chunk-Q4ZRBN2A.js} +1 -1
- package/dist/chunks/{chunk-HIYWSGI7.js → chunk-Q77ALSXR.js} +3 -0
- package/dist/chunks/{chunk-6TPH3ZBU.js → chunk-RCUMYP4L.js} +4 -4
- package/dist/chunks/{chunk-574PHXNT.js → chunk-U2NYO6GP.js} +1 -1
- package/dist/chunks/{chunk-6A62YUBE.js → chunk-UI2T3GI4.js} +2 -2
- package/dist/chunks/{chunk-UZD3DM6V.js → chunk-ULNWA6GY.js} +1 -1
- package/dist/chunks/{chunk-CENOYXK3.js → chunk-VLQBXXOQ.js} +2 -2
- package/dist/chunks/{compile-vercel-config-ATU3UBFK.js → compile-vercel-config-7THB6MTJ.js} +2 -2
- package/dist/chunks/{delete-WIN4UHQY.js → delete-USWDARFF.js} +3 -3
- package/dist/chunks/{disable-24KUO3TS.js → disable-K6B26MC2.js} +3 -3
- package/dist/chunks/{discard-B6ATZCPD.js → discard-2T7HZCGR.js} +3 -3
- package/dist/chunks/{edit-DIYIVLFQ.js → edit-2CC2WAO4.js} +5 -5
- package/dist/chunks/{enable-BF7NKTV7.js → enable-KEZA6F4T.js} +3 -3
- package/dist/chunks/{export-HHONDN7V.js → export-PE2T4HYP.js} +3 -3
- package/dist/chunks/{inspect-GSYKUMK5.js → inspect-TQSHD4MH.js} +4 -4
- package/dist/chunks/{list-OSJGB5AE.js → list-AU6URG3E.js} +4 -4
- package/dist/chunks/{list-PZ4DRWLO.js → list-IDTF5TWY.js} +3 -3
- package/dist/chunks/{ls-QBCHGSIC.js → ls-XOAWRTNQ.js} +5 -5
- package/dist/chunks/{publish-QYPZQ66O.js → publish-G42C77TP.js} +3 -3
- package/dist/chunks/{query-BDMX4CF6.js → query-YTBD7YLX.js} +3 -3
- package/dist/chunks/{reorder-YDTGTTJB.js → reorder-BDOOUURL.js} +3 -3
- package/dist/chunks/{restore-LXO2ZBAF.js → restore-ENUHC25O.js} +3 -3
- package/dist/chunks/{rm-3L7FVCDA.js → rm-ALWF3NBL.js} +5 -5
- package/dist/chunks/{routes-YEU33SON.js → routes-KUTLDFIF.js} +2 -2
- package/dist/chunks/{rule-inspect-T57QBYJR.js → rule-inspect-BV6MC7PG.js} +5 -5
- package/dist/chunks/{rules-E5DTNMFG.js → rules-IGG7M2AC.js} +6 -6
- package/dist/chunks/{schema-VYVJ4GYP.js → schema-ZYJOJIGL.js} +3 -3
- package/dist/chunks/{update-LT3LZVEZ.js → update-I3WE3IQJ.js} +5 -5
- package/dist/commands/build/index.js +18 -18
- package/dist/commands/deploy/index.js +12 -12
- package/dist/commands/dev/index.js +670 -100
- package/dist/commands/env/index.js +6 -6
- package/dist/commands/link/index.js +47 -13
- package/dist/commands/list/index.js +5 -5
- package/dist/commands-bulk.js +88 -45
- package/dist/index.js +46 -42
- package/dist/version.mjs +1 -1
- package/package.json +20 -19
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "../../chunks/chunk-2HSQ7YUK.js";
|
|
10
10
|
import {
|
|
11
11
|
getUpdateCommand
|
|
12
|
-
} from "../../chunks/chunk-
|
|
12
|
+
} from "../../chunks/chunk-HXAMK45D.js";
|
|
13
13
|
import {
|
|
14
14
|
highlight
|
|
15
15
|
} from "../../chunks/chunk-V5P25P7F.js";
|
|
@@ -26,28 +26,29 @@ import {
|
|
|
26
26
|
require_mime_types,
|
|
27
27
|
require_npa,
|
|
28
28
|
staticFiles
|
|
29
|
-
} from "../../chunks/chunk-
|
|
29
|
+
} from "../../chunks/chunk-7CTLNKAS.js";
|
|
30
30
|
import "../../chunks/chunk-IB5L4LKZ.js";
|
|
31
31
|
import {
|
|
32
32
|
pickOverrides
|
|
33
|
-
} from "../../chunks/chunk-
|
|
33
|
+
} from "../../chunks/chunk-MSWXRAHA.js";
|
|
34
34
|
import "../../chunks/chunk-YI3JV6GM.js";
|
|
35
35
|
import {
|
|
36
36
|
displayDetectedServices,
|
|
37
37
|
printProjectNotFoundError,
|
|
38
38
|
readConfig,
|
|
39
39
|
setupAndLink
|
|
40
|
-
} from "../../chunks/chunk-
|
|
40
|
+
} from "../../chunks/chunk-76QQSALN.js";
|
|
41
41
|
import "../../chunks/chunk-QH7WYDEP.js";
|
|
42
42
|
import {
|
|
43
43
|
getLocalPathConfig
|
|
44
|
-
} from "../../chunks/chunk-
|
|
45
|
-
import "../../chunks/chunk-
|
|
44
|
+
} from "../../chunks/chunk-ULNWA6GY.js";
|
|
45
|
+
import "../../chunks/chunk-FBYYZKN3.js";
|
|
46
46
|
import {
|
|
47
47
|
help
|
|
48
|
-
} from "../../chunks/chunk-
|
|
48
|
+
} from "../../chunks/chunk-3NR6OYDV.js";
|
|
49
49
|
import {
|
|
50
50
|
VERCEL_DIR,
|
|
51
|
+
VERCEL_OIDC_TOKEN,
|
|
51
52
|
findRepoRoot,
|
|
52
53
|
getLinkedProject,
|
|
53
54
|
getVercelDirectory,
|
|
@@ -69,10 +70,10 @@ import {
|
|
|
69
70
|
resolveProjectCwd,
|
|
70
71
|
tryDetectServices,
|
|
71
72
|
validateConfig
|
|
72
|
-
} from "../../chunks/chunk-
|
|
73
|
+
} from "../../chunks/chunk-INFYZRHS.js";
|
|
73
74
|
import {
|
|
74
75
|
TelemetryClient
|
|
75
|
-
} from "../../chunks/chunk-
|
|
76
|
+
} from "../../chunks/chunk-Q77ALSXR.js";
|
|
76
77
|
import {
|
|
77
78
|
buildCommandWithYes,
|
|
78
79
|
outputActionRequired
|
|
@@ -4821,7 +4822,7 @@ var require_requires_port = __commonJS({
|
|
|
4821
4822
|
var require_common = __commonJS({
|
|
4822
4823
|
"../../node_modules/.pnpm/http-proxy-node16@1.0.6_debug@3.1.0/node_modules/http-proxy-node16/lib/http-proxy/common.js"(exports2) {
|
|
4823
4824
|
var common = exports2;
|
|
4824
|
-
var
|
|
4825
|
+
var url4 = __require("url");
|
|
4825
4826
|
var extend = Object.assign;
|
|
4826
4827
|
var required = require_requires_port();
|
|
4827
4828
|
var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i;
|
|
@@ -4869,7 +4870,7 @@ var require_common = __commonJS({
|
|
|
4869
4870
|
}
|
|
4870
4871
|
var target = options[forward || "target"];
|
|
4871
4872
|
var targetPath = target && options.prependPath !== false ? target.path || "" : "";
|
|
4872
|
-
var outgoingPath = !options.toProxy ?
|
|
4873
|
+
var outgoingPath = !options.toProxy ? url4.parse(req.url).path || "" : req.url;
|
|
4873
4874
|
outgoingPath = !options.ignorePath ? outgoingPath : "";
|
|
4874
4875
|
outgoing.path = common.urlJoin(targetPath, outgoingPath);
|
|
4875
4876
|
if (options.changeOrigin) {
|
|
@@ -4892,11 +4893,11 @@ var require_common = __commonJS({
|
|
|
4892
4893
|
};
|
|
4893
4894
|
common.urlJoin = function() {
|
|
4894
4895
|
var args2 = Array.prototype.slice.call(arguments), queryParams = [], queryParamRaw = "", retSegs;
|
|
4895
|
-
args2.forEach((
|
|
4896
|
-
var qpStart =
|
|
4896
|
+
args2.forEach((url5, index) => {
|
|
4897
|
+
var qpStart = url5.indexOf("?");
|
|
4897
4898
|
if (qpStart !== -1) {
|
|
4898
|
-
queryParams.push(
|
|
4899
|
-
args2[index] =
|
|
4899
|
+
queryParams.push(url5.substring(qpStart + 1));
|
|
4900
|
+
args2[index] = url5.substring(0, qpStart);
|
|
4900
4901
|
}
|
|
4901
4902
|
});
|
|
4902
4903
|
queryParamRaw = queryParams.filter(Boolean).join("&");
|
|
@@ -4934,7 +4935,7 @@ var require_common = __commonJS({
|
|
|
4934
4935
|
// ../../node_modules/.pnpm/http-proxy-node16@1.0.6_debug@3.1.0/node_modules/http-proxy-node16/lib/http-proxy/passes/web-outgoing.js
|
|
4935
4936
|
var require_web_outgoing = __commonJS({
|
|
4936
4937
|
"../../node_modules/.pnpm/http-proxy-node16@1.0.6_debug@3.1.0/node_modules/http-proxy-node16/lib/http-proxy/passes/web-outgoing.js"(exports2, module2) {
|
|
4937
|
-
var
|
|
4938
|
+
var url4 = __require("url");
|
|
4938
4939
|
var common = require_common();
|
|
4939
4940
|
var redirectRegex = /^201|30(1|2|7|8)$/;
|
|
4940
4941
|
module2.exports = {
|
|
@@ -4972,8 +4973,8 @@ var require_web_outgoing = __commonJS({
|
|
|
4972
4973
|
},
|
|
4973
4974
|
setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) {
|
|
4974
4975
|
if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite) && proxyRes.headers["location"] && redirectRegex.test(proxyRes.statusCode)) {
|
|
4975
|
-
var target =
|
|
4976
|
-
var u =
|
|
4976
|
+
var target = url4.parse(options.target);
|
|
4977
|
+
var u = url4.parse(proxyRes.headers["location"]);
|
|
4977
4978
|
if (target.host != u.host) {
|
|
4978
4979
|
return;
|
|
4979
4980
|
}
|
|
@@ -5652,8 +5653,8 @@ var require_debug2 = __commonJS({
|
|
|
5652
5653
|
// ../../node_modules/.pnpm/follow-redirects@1.16.0_debug@3.1.0/node_modules/follow-redirects/index.js
|
|
5653
5654
|
var require_follow_redirects = __commonJS({
|
|
5654
5655
|
"../../node_modules/.pnpm/follow-redirects@1.16.0_debug@3.1.0/node_modules/follow-redirects/index.js"(exports2, module2) {
|
|
5655
|
-
var
|
|
5656
|
-
var URL2 =
|
|
5656
|
+
var url4 = __require("url");
|
|
5657
|
+
var URL2 = url4.URL;
|
|
5657
5658
|
var http2 = __require("http");
|
|
5658
5659
|
var https = __require("https");
|
|
5659
5660
|
var Writable2 = __require("stream").Writable;
|
|
@@ -5914,7 +5915,7 @@ var require_follow_redirects = __commonJS({
|
|
|
5914
5915
|
for (var event of events) {
|
|
5915
5916
|
request.on(event, eventHandlers[event]);
|
|
5916
5917
|
}
|
|
5917
|
-
this._currentUrl = /^\//.test(this._options.path) ?
|
|
5918
|
+
this._currentUrl = /^\//.test(this._options.path) ? url4.format(this._options) : (
|
|
5918
5919
|
// When making a request to a proxy, […]
|
|
5919
5920
|
// a client MUST send the target URI in absolute-form […].
|
|
5920
5921
|
this._options.path
|
|
@@ -5982,7 +5983,7 @@ var require_follow_redirects = __commonJS({
|
|
|
5982
5983
|
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
|
|
5983
5984
|
var currentUrlParts = parseUrl(this._currentUrl);
|
|
5984
5985
|
var currentHost = currentHostHeader || currentUrlParts.host;
|
|
5985
|
-
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
|
|
5986
|
+
var currentUrl = /^\w+:/.test(location) ? this._currentUrl : url4.format(Object.assign(currentUrlParts, { host: currentHost }));
|
|
5986
5987
|
var redirectUrl = resolveUrl(location, currentUrl);
|
|
5987
5988
|
debug("redirecting to", redirectUrl.href);
|
|
5988
5989
|
this._isRedirect = true;
|
|
@@ -6060,7 +6061,7 @@ var require_follow_redirects = __commonJS({
|
|
|
6060
6061
|
if (useNativeURL) {
|
|
6061
6062
|
parsed = new URL2(input);
|
|
6062
6063
|
} else {
|
|
6063
|
-
parsed = validateUrl(
|
|
6064
|
+
parsed = validateUrl(url4.parse(input));
|
|
6064
6065
|
if (!isString(parsed.protocol)) {
|
|
6065
6066
|
throw new InvalidUrlError({ input });
|
|
6066
6067
|
}
|
|
@@ -6068,7 +6069,7 @@ var require_follow_redirects = __commonJS({
|
|
|
6068
6069
|
return parsed;
|
|
6069
6070
|
}
|
|
6070
6071
|
function resolveUrl(relative3, base) {
|
|
6071
|
-
return useNativeURL ? new URL2(relative3, base) : parseUrl(
|
|
6072
|
+
return useNativeURL ? new URL2(relative3, base) : parseUrl(url4.resolve(base, relative3));
|
|
6072
6073
|
}
|
|
6073
6074
|
function validateUrl(input) {
|
|
6074
6075
|
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
|
@@ -6285,16 +6286,16 @@ var require_web_incoming = __commonJS({
|
|
|
6285
6286
|
var proxyError = createErrorHandler(proxyReq, options.target);
|
|
6286
6287
|
req.on("error", proxyError);
|
|
6287
6288
|
proxyReq.on("error", proxyError);
|
|
6288
|
-
function createErrorHandler(proxyReq2,
|
|
6289
|
+
function createErrorHandler(proxyReq2, url4) {
|
|
6289
6290
|
return function proxyError2(err) {
|
|
6290
6291
|
if (req.socket.destroyed && err.code === "ECONNRESET") {
|
|
6291
|
-
server.emit("econnreset", err, req, res,
|
|
6292
|
+
server.emit("econnreset", err, req, res, url4);
|
|
6292
6293
|
return proxyReq2.abort();
|
|
6293
6294
|
}
|
|
6294
6295
|
if (clb) {
|
|
6295
|
-
clb(err, req, res,
|
|
6296
|
+
clb(err, req, res, url4);
|
|
6296
6297
|
} else {
|
|
6297
|
-
server.emit("error", err, req, res,
|
|
6298
|
+
server.emit("error", err, req, res, url4);
|
|
6298
6299
|
}
|
|
6299
6300
|
};
|
|
6300
6301
|
}
|
|
@@ -15783,7 +15784,7 @@ var require_src2 = __commonJS({
|
|
|
15783
15784
|
var path6 = __require("path");
|
|
15784
15785
|
var { createHash } = __require("crypto");
|
|
15785
15786
|
var { realpath, lstat, createReadStream, readdir } = __require("fs");
|
|
15786
|
-
var
|
|
15787
|
+
var url4 = require_urlparser();
|
|
15787
15788
|
var slasher = require_glob_slash();
|
|
15788
15789
|
var minimatch3 = require_minimatch2();
|
|
15789
15790
|
var pathToRegExp = require_path_to_regexp();
|
|
@@ -15835,7 +15836,7 @@ var require_src2 = __commonJS({
|
|
|
15835
15836
|
}
|
|
15836
15837
|
const { keys, results } = matches;
|
|
15837
15838
|
const props = {};
|
|
15838
|
-
const { protocol } =
|
|
15839
|
+
const { protocol } = url4.parse(destination);
|
|
15839
15840
|
const normalizedDest = protocol ? destination : slasher(destination);
|
|
15840
15841
|
const toPath = pathToRegExp.compile(normalizedDest);
|
|
15841
15842
|
for (let index = 0; index < keys.length; index++) {
|
|
@@ -16190,7 +16191,7 @@ var require_src2 = __commonJS({
|
|
|
16190
16191
|
acceptsJSON = request.headers.accept.includes("application/json");
|
|
16191
16192
|
}
|
|
16192
16193
|
try {
|
|
16193
|
-
relativePath = decodeURIComponent(
|
|
16194
|
+
relativePath = decodeURIComponent(url4.parse(request.url).pathname);
|
|
16194
16195
|
} catch (err) {
|
|
16195
16196
|
return sendError("/", response, acceptsJSON, current, handlers, config, {
|
|
16196
16197
|
statusCode: 400,
|
|
@@ -16771,7 +16772,7 @@ var import_once = __toESM(require_dist7(), 1);
|
|
|
16771
16772
|
var import_directory = __toESM(require_directory(), 1);
|
|
16772
16773
|
var import_get_port2 = __toESM(require_get_port(), 1);
|
|
16773
16774
|
var import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);
|
|
16774
|
-
import
|
|
16775
|
+
import url3, { URL } from "url";
|
|
16775
16776
|
import http from "http";
|
|
16776
16777
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
16777
16778
|
import { watch } from "chokidar";
|
|
@@ -16831,7 +16832,7 @@ function relative2(a, b) {
|
|
|
16831
16832
|
|
|
16832
16833
|
// src/util/dev/router.ts
|
|
16833
16834
|
var import_pcre_to_regexp = __toESM(require_dist6(), 1);
|
|
16834
|
-
import
|
|
16835
|
+
import url2 from "url";
|
|
16835
16836
|
|
|
16836
16837
|
// src/util/dev/is-url.ts
|
|
16837
16838
|
function isURL(str) {
|
|
@@ -16885,6 +16886,343 @@ function formatQueryString(query) {
|
|
|
16885
16886
|
return s || null;
|
|
16886
16887
|
}
|
|
16887
16888
|
|
|
16889
|
+
// src/util/dev/transforms.ts
|
|
16890
|
+
import url from "url";
|
|
16891
|
+
function resolveTransforms(transforms, ctx) {
|
|
16892
|
+
if (!transforms || transforms.length === 0) {
|
|
16893
|
+
return [];
|
|
16894
|
+
}
|
|
16895
|
+
return transforms.map((transform) => {
|
|
16896
|
+
if (transform.type === "request.path") {
|
|
16897
|
+
return {
|
|
16898
|
+
...transform,
|
|
16899
|
+
args: resolveString(transform.args, transform, ctx)
|
|
16900
|
+
};
|
|
16901
|
+
}
|
|
16902
|
+
return {
|
|
16903
|
+
...transform,
|
|
16904
|
+
target: { key: resolveKey(transform.target.key, transform, ctx) },
|
|
16905
|
+
args: resolveArgs(transform.args, transform, ctx)
|
|
16906
|
+
};
|
|
16907
|
+
});
|
|
16908
|
+
}
|
|
16909
|
+
function applyResponseTransforms(headers, transforms) {
|
|
16910
|
+
for (const transform of transforms) {
|
|
16911
|
+
if (transform.type === "response.headers" && "target" in transform) {
|
|
16912
|
+
applyTransform(headers, transform, true);
|
|
16913
|
+
}
|
|
16914
|
+
}
|
|
16915
|
+
}
|
|
16916
|
+
function applyRequestTransforms(req, transforms) {
|
|
16917
|
+
if (transforms.length === 0) {
|
|
16918
|
+
return;
|
|
16919
|
+
}
|
|
16920
|
+
applyRequestHeaderTransforms(req.headers, transforms);
|
|
16921
|
+
const parsed = url.parse(req.url || "/");
|
|
16922
|
+
const query = parseQueryString(parsed.search);
|
|
16923
|
+
applyQueryTransforms(query, transforms);
|
|
16924
|
+
const newPath = getRequestPath(transforms);
|
|
16925
|
+
if (newPath !== void 0) {
|
|
16926
|
+
parsed.pathname = newPath;
|
|
16927
|
+
}
|
|
16928
|
+
parsed.search = formatQueryString(query);
|
|
16929
|
+
req.url = url.format(parsed);
|
|
16930
|
+
}
|
|
16931
|
+
function hasResponseTransforms(transforms) {
|
|
16932
|
+
return transforms.some((t) => t.type === "response.headers");
|
|
16933
|
+
}
|
|
16934
|
+
function resolveKey(key, _transform, ctx) {
|
|
16935
|
+
if (typeof key === "string") {
|
|
16936
|
+
return expandCaptureGroups(key, ctx.match, ctx.keys);
|
|
16937
|
+
}
|
|
16938
|
+
return key;
|
|
16939
|
+
}
|
|
16940
|
+
function resolveArgs(args2, transform, ctx) {
|
|
16941
|
+
if (typeof args2 === "string") {
|
|
16942
|
+
return resolveString(args2, transform, ctx);
|
|
16943
|
+
}
|
|
16944
|
+
if (Array.isArray(args2)) {
|
|
16945
|
+
return args2.map(
|
|
16946
|
+
(a) => typeof a === "string" ? resolveString(a, transform, ctx) : a
|
|
16947
|
+
);
|
|
16948
|
+
}
|
|
16949
|
+
return args2;
|
|
16950
|
+
}
|
|
16951
|
+
function resolveString(value, transform, ctx) {
|
|
16952
|
+
let resolved = expandCaptureGroups(value, ctx.match, ctx.keys);
|
|
16953
|
+
if (transform.env && transform.env.length > 0 && ctx.env) {
|
|
16954
|
+
resolved = expandEnvVars(resolved, transform.env, ctx.env);
|
|
16955
|
+
}
|
|
16956
|
+
return resolved;
|
|
16957
|
+
}
|
|
16958
|
+
function expandCaptureGroups(str, match, keys) {
|
|
16959
|
+
return str.replace(/\$([0-9A-Za-z_]+)/g, (whole, name) => {
|
|
16960
|
+
const namedIdx = keys.indexOf(name);
|
|
16961
|
+
if (namedIdx !== -1) {
|
|
16962
|
+
return match[namedIdx + 1] ?? "";
|
|
16963
|
+
}
|
|
16964
|
+
if (/^[0-9]+$/.test(name)) {
|
|
16965
|
+
const n = parseInt(name, 10);
|
|
16966
|
+
if (n < match.length) {
|
|
16967
|
+
return match[n] ?? "";
|
|
16968
|
+
}
|
|
16969
|
+
}
|
|
16970
|
+
return whole;
|
|
16971
|
+
});
|
|
16972
|
+
}
|
|
16973
|
+
function expandEnvVars(str, allowlist, env) {
|
|
16974
|
+
const allowed = new Set(allowlist);
|
|
16975
|
+
return str.replace(
|
|
16976
|
+
/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g,
|
|
16977
|
+
(match, braced, bare) => {
|
|
16978
|
+
const name = braced ?? bare;
|
|
16979
|
+
if (!allowed.has(name) || env[name] === void 0) {
|
|
16980
|
+
return match;
|
|
16981
|
+
}
|
|
16982
|
+
return env[name];
|
|
16983
|
+
}
|
|
16984
|
+
);
|
|
16985
|
+
}
|
|
16986
|
+
function applyRequestHeaderTransforms(headers, transforms) {
|
|
16987
|
+
for (const transform of transforms) {
|
|
16988
|
+
if (transform.type === "request.headers" && "target" in transform) {
|
|
16989
|
+
applyTransform(headers, transform, true);
|
|
16990
|
+
}
|
|
16991
|
+
}
|
|
16992
|
+
}
|
|
16993
|
+
function applyQueryTransforms(query, transforms) {
|
|
16994
|
+
for (const transform of transforms) {
|
|
16995
|
+
if (transform.type === "request.query" && "target" in transform) {
|
|
16996
|
+
applyTransform(query, transform, false);
|
|
16997
|
+
}
|
|
16998
|
+
}
|
|
16999
|
+
for (const key of Object.keys(query)) {
|
|
17000
|
+
const value = query[key];
|
|
17001
|
+
if (value === void 0) {
|
|
17002
|
+
delete query[key];
|
|
17003
|
+
} else if (typeof value === "string") {
|
|
17004
|
+
query[key] = [value];
|
|
17005
|
+
}
|
|
17006
|
+
}
|
|
17007
|
+
}
|
|
17008
|
+
var HEADER_NAME_RE = /^[-\w]+$/;
|
|
17009
|
+
var HEADER_VALUE_RE = /^[-\w:;.,/\\"'?!(){}[\]@<>=+*#$&`|~%^ ]+$/;
|
|
17010
|
+
function isValidHeaderName(name) {
|
|
17011
|
+
return name.length > 0 && HEADER_NAME_RE.test(name);
|
|
17012
|
+
}
|
|
17013
|
+
function isValidHeaderValue(value) {
|
|
17014
|
+
return value.length > 0 && HEADER_VALUE_RE.test(value);
|
|
17015
|
+
}
|
|
17016
|
+
function hasValidHeaderArgs(args2) {
|
|
17017
|
+
if (typeof args2 === "string") {
|
|
17018
|
+
return isValidHeaderValue(args2);
|
|
17019
|
+
}
|
|
17020
|
+
if (Array.isArray(args2)) {
|
|
17021
|
+
return args2.every(isValidHeaderValue);
|
|
17022
|
+
}
|
|
17023
|
+
return false;
|
|
17024
|
+
}
|
|
17025
|
+
function applyTransform(data, transform, isHeader) {
|
|
17026
|
+
const keySelector = transform.target?.key;
|
|
17027
|
+
if (keySelector == null) {
|
|
17028
|
+
return;
|
|
17029
|
+
}
|
|
17030
|
+
if (isHeader && (transform.op === "set" || transform.op === "append")) {
|
|
17031
|
+
if (typeof keySelector === "string" && !isValidHeaderName(keySelector)) {
|
|
17032
|
+
return;
|
|
17033
|
+
}
|
|
17034
|
+
if (!hasValidHeaderArgs(transform.args)) {
|
|
17035
|
+
return;
|
|
17036
|
+
}
|
|
17037
|
+
}
|
|
17038
|
+
const matchedKeys = findMatchingKeys(data, keySelector);
|
|
17039
|
+
switch (transform.op) {
|
|
17040
|
+
case "set":
|
|
17041
|
+
opSet(data, matchedKeys, keySelector, transform.args);
|
|
17042
|
+
break;
|
|
17043
|
+
case "append":
|
|
17044
|
+
opAppend(data, matchedKeys, keySelector, transform.args, isHeader);
|
|
17045
|
+
break;
|
|
17046
|
+
case "delete":
|
|
17047
|
+
opDelete(data, matchedKeys, transform.args, isHeader);
|
|
17048
|
+
break;
|
|
17049
|
+
default:
|
|
17050
|
+
break;
|
|
17051
|
+
}
|
|
17052
|
+
}
|
|
17053
|
+
function isValidRequestPath(path6) {
|
|
17054
|
+
if (path6 === "" || path6.length > 2048) {
|
|
17055
|
+
return false;
|
|
17056
|
+
}
|
|
17057
|
+
if (path6[0] !== "/" || path6.startsWith("//")) {
|
|
17058
|
+
return false;
|
|
17059
|
+
}
|
|
17060
|
+
if (/[?#]/.test(path6)) {
|
|
17061
|
+
return false;
|
|
17062
|
+
}
|
|
17063
|
+
for (let i = 0; i < path6.length; i++) {
|
|
17064
|
+
const code = path6.charCodeAt(i);
|
|
17065
|
+
if (code <= 32 || code === 127) {
|
|
17066
|
+
return false;
|
|
17067
|
+
}
|
|
17068
|
+
}
|
|
17069
|
+
return true;
|
|
17070
|
+
}
|
|
17071
|
+
function getRequestPath(transforms) {
|
|
17072
|
+
let path6;
|
|
17073
|
+
for (const transform of transforms) {
|
|
17074
|
+
if (transform.type === "request.path" && transform.op === "set" && typeof transform.args === "string" && isValidRequestPath(transform.args)) {
|
|
17075
|
+
path6 = transform.args;
|
|
17076
|
+
}
|
|
17077
|
+
}
|
|
17078
|
+
return path6;
|
|
17079
|
+
}
|
|
17080
|
+
function findMatchingKeys(data, keyPattern) {
|
|
17081
|
+
const matched = [];
|
|
17082
|
+
for (const key of Object.keys(data)) {
|
|
17083
|
+
if (matchesRule(key, keyPattern)) {
|
|
17084
|
+
matched.push(key);
|
|
17085
|
+
}
|
|
17086
|
+
}
|
|
17087
|
+
return matched;
|
|
17088
|
+
}
|
|
17089
|
+
function matchesRule(candidate, rule) {
|
|
17090
|
+
candidate = candidate.toLowerCase();
|
|
17091
|
+
if (rule == null) {
|
|
17092
|
+
return true;
|
|
17093
|
+
}
|
|
17094
|
+
if (typeof rule === "string") {
|
|
17095
|
+
return candidate === rule.toLowerCase();
|
|
17096
|
+
}
|
|
17097
|
+
const r = rule;
|
|
17098
|
+
for (const [op, val] of Object.entries(r)) {
|
|
17099
|
+
if (val === void 0) {
|
|
17100
|
+
continue;
|
|
17101
|
+
}
|
|
17102
|
+
switch (op) {
|
|
17103
|
+
case "eq":
|
|
17104
|
+
if (candidate !== String(val).toLowerCase())
|
|
17105
|
+
return false;
|
|
17106
|
+
break;
|
|
17107
|
+
case "neq":
|
|
17108
|
+
if (candidate === val.toLowerCase())
|
|
17109
|
+
return false;
|
|
17110
|
+
break;
|
|
17111
|
+
case "inc":
|
|
17112
|
+
if (!val.some((v) => candidate === v.toLowerCase()))
|
|
17113
|
+
return false;
|
|
17114
|
+
break;
|
|
17115
|
+
case "ninc":
|
|
17116
|
+
if (val.some((v) => candidate === v.toLowerCase()))
|
|
17117
|
+
return false;
|
|
17118
|
+
break;
|
|
17119
|
+
case "pre":
|
|
17120
|
+
if (!candidate.startsWith(String(val).toLowerCase()))
|
|
17121
|
+
return false;
|
|
17122
|
+
break;
|
|
17123
|
+
case "suf":
|
|
17124
|
+
if (!candidate.endsWith(String(val).toLowerCase()))
|
|
17125
|
+
return false;
|
|
17126
|
+
break;
|
|
17127
|
+
case "sub":
|
|
17128
|
+
if (!candidate.includes(String(val).toLowerCase()))
|
|
17129
|
+
return false;
|
|
17130
|
+
break;
|
|
17131
|
+
case "gt":
|
|
17132
|
+
if (!(Number(candidate) > val))
|
|
17133
|
+
return false;
|
|
17134
|
+
break;
|
|
17135
|
+
case "gte":
|
|
17136
|
+
if (!(Number(candidate) >= val))
|
|
17137
|
+
return false;
|
|
17138
|
+
break;
|
|
17139
|
+
case "lt":
|
|
17140
|
+
if (!(Number(candidate) < val))
|
|
17141
|
+
return false;
|
|
17142
|
+
break;
|
|
17143
|
+
case "lte":
|
|
17144
|
+
if (!(Number(candidate) <= val))
|
|
17145
|
+
return false;
|
|
17146
|
+
break;
|
|
17147
|
+
default:
|
|
17148
|
+
break;
|
|
17149
|
+
}
|
|
17150
|
+
}
|
|
17151
|
+
return true;
|
|
17152
|
+
}
|
|
17153
|
+
function opSet(data, matchedKeys, keySelector, args2) {
|
|
17154
|
+
for (const key of matchedKeys) {
|
|
17155
|
+
data[key] = args2;
|
|
17156
|
+
}
|
|
17157
|
+
if (matchedKeys.length === 0 && typeof keySelector === "string" && data[keySelector] === void 0 && !isEmptyArgs(args2)) {
|
|
17158
|
+
data[keySelector] = args2;
|
|
17159
|
+
}
|
|
17160
|
+
}
|
|
17161
|
+
function opAppend(data, matchedKeys, keySelector, args2, isHeader) {
|
|
17162
|
+
if (isEmptyArgs(args2)) {
|
|
17163
|
+
return;
|
|
17164
|
+
}
|
|
17165
|
+
const toAppend = typeof args2 === "string" ? [args2] : args2 ?? [];
|
|
17166
|
+
for (const key of matchedKeys) {
|
|
17167
|
+
const next = [...toValueList(data[key], isHeader), ...toAppend];
|
|
17168
|
+
setTransformValue(data, key, fromValueList(next));
|
|
17169
|
+
}
|
|
17170
|
+
if (matchedKeys.length === 0 && typeof keySelector === "string") {
|
|
17171
|
+
setTransformValue(data, keySelector, fromValueList(toAppend));
|
|
17172
|
+
}
|
|
17173
|
+
}
|
|
17174
|
+
function opDelete(data, matchedKeys, args2, isHeader) {
|
|
17175
|
+
if (args2 == null) {
|
|
17176
|
+
for (const key of matchedKeys) {
|
|
17177
|
+
delete data[key];
|
|
17178
|
+
}
|
|
17179
|
+
return;
|
|
17180
|
+
}
|
|
17181
|
+
const patterns = typeof args2 === "string" ? [args2] : args2;
|
|
17182
|
+
for (const key of matchedKeys) {
|
|
17183
|
+
const kept = toValueList(data[key], isHeader).filter(
|
|
17184
|
+
(value) => !patterns.some((pattern) => matchesRule(value, pattern))
|
|
17185
|
+
);
|
|
17186
|
+
setTransformValue(data, key, fromValueList(kept));
|
|
17187
|
+
}
|
|
17188
|
+
}
|
|
17189
|
+
function toValueList(value, isHeader) {
|
|
17190
|
+
if (value === void 0) {
|
|
17191
|
+
return [];
|
|
17192
|
+
}
|
|
17193
|
+
if (Array.isArray(value)) {
|
|
17194
|
+
return value;
|
|
17195
|
+
}
|
|
17196
|
+
const str = String(value);
|
|
17197
|
+
if (isHeader && str.includes(",")) {
|
|
17198
|
+
return str.split(",").map((v) => v.trim()).filter((v) => v !== "");
|
|
17199
|
+
}
|
|
17200
|
+
return [str];
|
|
17201
|
+
}
|
|
17202
|
+
function fromValueList(values) {
|
|
17203
|
+
if (values.length === 0) {
|
|
17204
|
+
return void 0;
|
|
17205
|
+
}
|
|
17206
|
+
if (values.length === 1) {
|
|
17207
|
+
return values[0];
|
|
17208
|
+
}
|
|
17209
|
+
return values;
|
|
17210
|
+
}
|
|
17211
|
+
function setTransformValue(data, key, value) {
|
|
17212
|
+
if (value === void 0) {
|
|
17213
|
+
delete data[key];
|
|
17214
|
+
} else {
|
|
17215
|
+
data[key] = value;
|
|
17216
|
+
}
|
|
17217
|
+
}
|
|
17218
|
+
function isEmptyArgs(args2) {
|
|
17219
|
+
if (args2 == null)
|
|
17220
|
+
return true;
|
|
17221
|
+
if (typeof args2 === "string")
|
|
17222
|
+
return args2 === "";
|
|
17223
|
+
return args2.length === 0;
|
|
17224
|
+
}
|
|
17225
|
+
|
|
16888
17226
|
// src/util/dev/router.ts
|
|
16889
17227
|
function resolveRouteParameters(str, match, keys) {
|
|
16890
17228
|
return str.replace(/\$([1-9a-zA-Z]+)/g, (_, param2) => {
|
|
@@ -16916,12 +17254,14 @@ function getRoutesTypes(routes = []) {
|
|
|
16916
17254
|
}
|
|
16917
17255
|
async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfig, previousHeaders, missRoutes, phase) {
|
|
16918
17256
|
let result;
|
|
16919
|
-
let { pathname: reqPathname, search: reqSearch } =
|
|
17257
|
+
let { pathname: reqPathname, search: reqSearch } = url2.parse(reqUrl);
|
|
16920
17258
|
reqPathname = reqPathname || "/";
|
|
16921
17259
|
const reqQuery = parseQueryString(reqSearch);
|
|
16922
17260
|
const combinedHeaders = { ...previousHeaders };
|
|
16923
17261
|
let status;
|
|
16924
17262
|
let isContinue = false;
|
|
17263
|
+
const requestTransforms = [];
|
|
17264
|
+
let responseTransforms;
|
|
16925
17265
|
if (routes) {
|
|
16926
17266
|
let idx = -1;
|
|
16927
17267
|
for (const routeConfig of routes) {
|
|
@@ -16939,6 +17279,15 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
16939
17279
|
const matcher = (0, import_pcre_to_regexp.default)(`%${src}%${flags}`, keys);
|
|
16940
17280
|
const match = matcher.exec(reqPathname) || matcher.exec(reqPathname.substring(1));
|
|
16941
17281
|
if (match) {
|
|
17282
|
+
const routeTransforms = routeConfig.transforms ? resolveTransforms(routeConfig.transforms, {
|
|
17283
|
+
match,
|
|
17284
|
+
keys,
|
|
17285
|
+
env: devServer?.envConfigs.runEnv
|
|
17286
|
+
}) : [];
|
|
17287
|
+
const isServiceMarker = typeof routeConfig.destination === "object" && routeConfig.destination !== null && routeConfig.destination.type === "service";
|
|
17288
|
+
if (!isServiceMarker && routeTransforms.length > 0) {
|
|
17289
|
+
requestTransforms.push(...routeTransforms);
|
|
17290
|
+
}
|
|
16942
17291
|
let destPath = reqPathname;
|
|
16943
17292
|
if (routeConfig.dest) {
|
|
16944
17293
|
destPath = resolveRouteParameters(routeConfig.dest, match, keys);
|
|
@@ -16958,13 +17307,16 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
16958
17307
|
if (routeConfig.status) {
|
|
16959
17308
|
status = routeConfig.status;
|
|
16960
17309
|
}
|
|
17310
|
+
if (routeTransforms.length > 0) {
|
|
17311
|
+
responseTransforms = routeTransforms;
|
|
17312
|
+
}
|
|
16961
17313
|
reqPathname = destPath;
|
|
16962
17314
|
isContinue = true;
|
|
16963
17315
|
continue;
|
|
16964
17316
|
}
|
|
16965
17317
|
const isDestUrl = isURL(destPath);
|
|
16966
17318
|
if (routeConfig.check && devServer && vercelConfig && phase !== "hit" && !isDestUrl) {
|
|
16967
|
-
let { pathname } =
|
|
17319
|
+
let { pathname } = url2.parse(destPath);
|
|
16968
17320
|
pathname = pathname || "/";
|
|
16969
17321
|
const hasDestFile = await devServer.hasFilesystem(
|
|
16970
17322
|
pathname,
|
|
@@ -16973,6 +17325,9 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
16973
17325
|
if (!hasDestFile) {
|
|
16974
17326
|
if (routeConfig.status && phase !== "miss") {
|
|
16975
17327
|
} else if (missRoutes && missRoutes.length > 0) {
|
|
17328
|
+
if (routeTransforms.length > 0) {
|
|
17329
|
+
responseTransforms = routeTransforms;
|
|
17330
|
+
}
|
|
16976
17331
|
const missResult = await devRouter(
|
|
16977
17332
|
destPath,
|
|
16978
17333
|
reqMethod,
|
|
@@ -16984,6 +17339,15 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
16984
17339
|
"miss"
|
|
16985
17340
|
);
|
|
16986
17341
|
if (missResult.found) {
|
|
17342
|
+
if (requestTransforms.length > 0) {
|
|
17343
|
+
missResult.requestTransforms = [
|
|
17344
|
+
...requestTransforms,
|
|
17345
|
+
...missResult.requestTransforms ?? []
|
|
17346
|
+
];
|
|
17347
|
+
}
|
|
17348
|
+
if (!missResult.responseTransforms && responseTransforms) {
|
|
17349
|
+
missResult.responseTransforms = responseTransforms;
|
|
17350
|
+
}
|
|
16987
17351
|
return missResult;
|
|
16988
17352
|
} else {
|
|
16989
17353
|
reqPathname = destPath;
|
|
@@ -16993,11 +17357,19 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
16993
17357
|
if (routeConfig.status && phase === "miss") {
|
|
16994
17358
|
status = routeConfig.status;
|
|
16995
17359
|
}
|
|
17360
|
+
if (routeTransforms.length > 0) {
|
|
17361
|
+
responseTransforms = routeTransforms;
|
|
17362
|
+
}
|
|
16996
17363
|
reqPathname = destPath;
|
|
16997
17364
|
continue;
|
|
16998
17365
|
}
|
|
16999
17366
|
}
|
|
17000
17367
|
}
|
|
17368
|
+
const effectiveStatus = routeConfig.status || status;
|
|
17369
|
+
const isRedirectExit = typeof effectiveStatus === "number" && effectiveStatus >= 300 && effectiveStatus < 400;
|
|
17370
|
+
if (!isServiceMarker && !isRedirectExit && routeTransforms.length > 0) {
|
|
17371
|
+
responseTransforms = routeTransforms;
|
|
17372
|
+
}
|
|
17001
17373
|
if (isDestUrl) {
|
|
17002
17374
|
result = {
|
|
17003
17375
|
found: true,
|
|
@@ -17010,14 +17382,16 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
17010
17382
|
query: reqQuery,
|
|
17011
17383
|
matched_route: routeConfig,
|
|
17012
17384
|
matched_route_idx: idx,
|
|
17013
|
-
phase
|
|
17385
|
+
phase,
|
|
17386
|
+
requestTransforms,
|
|
17387
|
+
responseTransforms
|
|
17014
17388
|
};
|
|
17015
17389
|
break;
|
|
17016
17390
|
} else {
|
|
17017
17391
|
if (!destPath.startsWith("/")) {
|
|
17018
17392
|
destPath = `/${destPath}`;
|
|
17019
17393
|
}
|
|
17020
|
-
let { pathname: destPathname, search: destSearch } =
|
|
17394
|
+
let { pathname: destPathname, search: destSearch } = url2.parse(destPath);
|
|
17021
17395
|
destPathname = destPathname || "/";
|
|
17022
17396
|
const destQuery = parseQueryString(destSearch);
|
|
17023
17397
|
Object.assign(destQuery, reqQuery);
|
|
@@ -17032,7 +17406,9 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
17032
17406
|
query: destQuery,
|
|
17033
17407
|
matched_route: routeConfig,
|
|
17034
17408
|
matched_route_idx: idx,
|
|
17035
|
-
phase
|
|
17409
|
+
phase,
|
|
17410
|
+
requestTransforms,
|
|
17411
|
+
responseTransforms
|
|
17036
17412
|
};
|
|
17037
17413
|
break;
|
|
17038
17414
|
}
|
|
@@ -17048,7 +17424,9 @@ async function devRouter(reqUrl = "/", reqMethod, routes, devServer, vercelConfi
|
|
|
17048
17424
|
isDestUrl: false,
|
|
17049
17425
|
query: reqQuery,
|
|
17050
17426
|
headers: combinedHeaders,
|
|
17051
|
-
phase
|
|
17427
|
+
phase,
|
|
17428
|
+
requestTransforms,
|
|
17429
|
+
responseTransforms
|
|
17052
17430
|
};
|
|
17053
17431
|
}
|
|
17054
17432
|
return result;
|
|
@@ -17923,6 +18301,7 @@ var ServicesOrchestrator = class {
|
|
|
17923
18301
|
constructor(options) {
|
|
17924
18302
|
this.managedServices = /* @__PURE__ */ new Map();
|
|
17925
18303
|
this.managedProcesses = /* @__PURE__ */ new Map();
|
|
18304
|
+
this.servicePorts = /* @__PURE__ */ new Map();
|
|
17926
18305
|
this.cronTimers = [];
|
|
17927
18306
|
this.stopping = false;
|
|
17928
18307
|
this.services = options.services;
|
|
@@ -17973,6 +18352,7 @@ var ServicesOrchestrator = class {
|
|
|
17973
18352
|
async startAll() {
|
|
17974
18353
|
output_manager_default.debug(`Starting ${this.services.length} services`);
|
|
17975
18354
|
this.registerExitBackstop();
|
|
18355
|
+
await this.allocateServicePorts();
|
|
17976
18356
|
const startPromises = this.services.map(
|
|
17977
18357
|
(service, index) => this.startService(service, index).then((result) => {
|
|
17978
18358
|
this.managedServices.set(result.name, result);
|
|
@@ -18120,6 +18500,19 @@ var ServicesOrchestrator = class {
|
|
|
18120
18500
|
getServices() {
|
|
18121
18501
|
return this.managedServices;
|
|
18122
18502
|
}
|
|
18503
|
+
// Pre-allocate ports for services in advance, can be subject for
|
|
18504
|
+
// TOCTOU but for dev purposes it shouldn't be an often case
|
|
18505
|
+
async allocateServicePorts() {
|
|
18506
|
+
const used = /* @__PURE__ */ new Set();
|
|
18507
|
+
for (const service of this.services) {
|
|
18508
|
+
let port = await (0, import_get_port.default)();
|
|
18509
|
+
while (used.has(port)) {
|
|
18510
|
+
port = await (0, import_get_port.default)();
|
|
18511
|
+
}
|
|
18512
|
+
used.add(port);
|
|
18513
|
+
this.servicePorts.set(service.name, port);
|
|
18514
|
+
}
|
|
18515
|
+
}
|
|
18123
18516
|
async startService(service, colorIndex) {
|
|
18124
18517
|
const logger = createServiceLogger(
|
|
18125
18518
|
service.name,
|
|
@@ -18127,8 +18520,17 @@ var ServicesOrchestrator = class {
|
|
|
18127
18520
|
this.maxNameLength
|
|
18128
18521
|
);
|
|
18129
18522
|
const spec = (0, import_fs_detectors2.isExperimentalServiceV2)(service) ? this.getV2StartSpec(service) : this.getV1StartSpec(service);
|
|
18523
|
+
const port = this.servicePorts.get(service.name);
|
|
18524
|
+
if (port !== void 0) {
|
|
18525
|
+
spec.env.VERCEL_DEV_PORT = String(port);
|
|
18526
|
+
}
|
|
18130
18527
|
if (spec.builderSpec) {
|
|
18131
|
-
const result = await this.tryStartWithBuilder(
|
|
18528
|
+
const result = await this.tryStartWithBuilder(
|
|
18529
|
+
service.name,
|
|
18530
|
+
spec,
|
|
18531
|
+
logger,
|
|
18532
|
+
port
|
|
18533
|
+
);
|
|
18132
18534
|
if (result) {
|
|
18133
18535
|
return result;
|
|
18134
18536
|
}
|
|
@@ -18148,7 +18550,8 @@ var ServicesOrchestrator = class {
|
|
|
18148
18550
|
logger,
|
|
18149
18551
|
builderConfig: spec.builderConfig,
|
|
18150
18552
|
routePrefixes: spec.routePrefixes,
|
|
18151
|
-
workspaceLabel: spec.rootLabel
|
|
18553
|
+
workspaceLabel: spec.rootLabel,
|
|
18554
|
+
port
|
|
18152
18555
|
});
|
|
18153
18556
|
}
|
|
18154
18557
|
getV1StartSpec(service) {
|
|
@@ -18224,12 +18627,28 @@ var ServicesOrchestrator = class {
|
|
|
18224
18627
|
}
|
|
18225
18628
|
getV2StartSpec(service) {
|
|
18226
18629
|
const framework = import_frameworks.frameworkList.find((f) => f.slug === service.framework);
|
|
18630
|
+
const effectiveProcessEnv = cloneEnv(this.envFilesValues, process.env);
|
|
18631
|
+
const perServiceEnv = {};
|
|
18632
|
+
for (const binding of service.bindings ?? []) {
|
|
18633
|
+
if (binding.type !== "service" || binding.format !== "url") {
|
|
18634
|
+
continue;
|
|
18635
|
+
}
|
|
18636
|
+
if (binding.env in effectiveProcessEnv) {
|
|
18637
|
+
continue;
|
|
18638
|
+
}
|
|
18639
|
+
const targetPort = this.servicePorts.get(binding.service);
|
|
18640
|
+
if (targetPort === void 0) {
|
|
18641
|
+
continue;
|
|
18642
|
+
}
|
|
18643
|
+
perServiceEnv[binding.env] = `http://127.0.0.1:${targetPort}/`;
|
|
18644
|
+
}
|
|
18227
18645
|
const env = cloneEnv(
|
|
18228
18646
|
{
|
|
18229
18647
|
FORCE_COLOR: process.stdout.isTTY ? "1" : "0",
|
|
18230
18648
|
BROWSER: "none"
|
|
18231
18649
|
},
|
|
18232
|
-
|
|
18650
|
+
effectiveProcessEnv,
|
|
18651
|
+
perServiceEnv
|
|
18233
18652
|
);
|
|
18234
18653
|
const root = service.root || ".";
|
|
18235
18654
|
return {
|
|
@@ -18252,7 +18671,7 @@ var ServicesOrchestrator = class {
|
|
|
18252
18671
|
}
|
|
18253
18672
|
// Start a service via its builder's `startDevServer`, if it exposes one.
|
|
18254
18673
|
// Returns null to fall back to a dev command
|
|
18255
|
-
async tryStartWithBuilder(name, spec, logger) {
|
|
18674
|
+
async tryStartWithBuilder(name, spec, logger, port) {
|
|
18256
18675
|
if (!spec.builderSpec) {
|
|
18257
18676
|
return null;
|
|
18258
18677
|
}
|
|
@@ -18284,6 +18703,7 @@ var ServicesOrchestrator = class {
|
|
|
18284
18703
|
meta: {
|
|
18285
18704
|
isDev: true,
|
|
18286
18705
|
env: spec.env,
|
|
18706
|
+
port,
|
|
18287
18707
|
serviceCount: this.services.length,
|
|
18288
18708
|
pythonServiceCount: this.pythonServiceCount,
|
|
18289
18709
|
syncDependencies: true,
|
|
@@ -18331,7 +18751,7 @@ var ServicesOrchestrator = class {
|
|
|
18331
18751
|
workspaceLabel
|
|
18332
18752
|
} = params;
|
|
18333
18753
|
await this.syncDependencies(builderConfig, workspacePath, logger);
|
|
18334
|
-
const port = await (0, import_get_port.default)();
|
|
18754
|
+
const port = params.port ?? await (0, import_get_port.default)();
|
|
18335
18755
|
env.PORT = `${port}`;
|
|
18336
18756
|
const nodeBinPaths = getNodeBinPaths({
|
|
18337
18757
|
base: this.repoRoot,
|
|
@@ -18526,8 +18946,8 @@ var ServicesOrchestrator = class {
|
|
|
18526
18946
|
`Triggering scheduled job ${import_chalk.default.bold(serviceName)} (schedule: ${import_chalk.default.cyan(schedule)})`
|
|
18527
18947
|
);
|
|
18528
18948
|
try {
|
|
18529
|
-
const
|
|
18530
|
-
const res = await fetch(
|
|
18949
|
+
const url4 = `http://${managed.host}:${managed.port}${cronPath}`;
|
|
18950
|
+
const res = await fetch(url4, { method: "POST" });
|
|
18531
18951
|
output_manager_default.debug(
|
|
18532
18952
|
`Cron trigger for "${serviceName}" responded with status ${res.status}`
|
|
18533
18953
|
);
|
|
@@ -18564,6 +18984,8 @@ var QueueBroker = class {
|
|
|
18564
18984
|
constructor(services, getServiceOrigin) {
|
|
18565
18985
|
this.getServiceOrigin = getServiceOrigin;
|
|
18566
18986
|
this.messages = /* @__PURE__ */ new Map();
|
|
18987
|
+
this.idempotencyRecords = /* @__PURE__ */ new Map();
|
|
18988
|
+
this.duplicateMessages = /* @__PURE__ */ new Map();
|
|
18567
18989
|
this.consumerGroups = [];
|
|
18568
18990
|
this.deliveryState = /* @__PURE__ */ new Map();
|
|
18569
18991
|
for (const service of services) {
|
|
@@ -18593,6 +19015,30 @@ var QueueBroker = class {
|
|
|
18593
19015
|
enqueue(queueName, payload, contentType2, options) {
|
|
18594
19016
|
const messageId = randomBytes(16).toString("hex");
|
|
18595
19017
|
const retentionMs = (options?.retentionSeconds ?? 0) > 0 ? options.retentionSeconds * 1e3 : DEFAULT_RETENTION;
|
|
19018
|
+
const idempotencyRecordKey = options?.idempotencyKey ? `${queueName}:${options.idempotencyKey}` : void 0;
|
|
19019
|
+
if (idempotencyRecordKey) {
|
|
19020
|
+
const record = this.idempotencyRecords.get(idempotencyRecordKey);
|
|
19021
|
+
if (record && record.expiresAt > Date.now()) {
|
|
19022
|
+
this.duplicateMessages.set(messageId, {
|
|
19023
|
+
queueName,
|
|
19024
|
+
originalMessageId: record.messageId,
|
|
19025
|
+
expiresAt: Date.now() + retentionMs
|
|
19026
|
+
});
|
|
19027
|
+
output_manager_default.debug(
|
|
19028
|
+
`queues: skipped duplicate message for queue "${queueName}"`
|
|
19029
|
+
);
|
|
19030
|
+
return { messageId };
|
|
19031
|
+
}
|
|
19032
|
+
if (record) {
|
|
19033
|
+
this.idempotencyRecords.delete(idempotencyRecordKey);
|
|
19034
|
+
}
|
|
19035
|
+
}
|
|
19036
|
+
if (idempotencyRecordKey) {
|
|
19037
|
+
this.idempotencyRecords.set(idempotencyRecordKey, {
|
|
19038
|
+
messageId,
|
|
19039
|
+
expiresAt: Date.now() + retentionMs
|
|
19040
|
+
});
|
|
19041
|
+
}
|
|
18596
19042
|
const message2 = {
|
|
18597
19043
|
messageId,
|
|
18598
19044
|
payload,
|
|
@@ -18634,6 +19080,17 @@ var QueueBroker = class {
|
|
|
18634
19080
|
}
|
|
18635
19081
|
return { messageId };
|
|
18636
19082
|
}
|
|
19083
|
+
getOriginalMessageIdForDuplicate(queueName, messageId) {
|
|
19084
|
+
const duplicate = this.duplicateMessages.get(messageId);
|
|
19085
|
+
if (!duplicate || duplicate.queueName !== queueName) {
|
|
19086
|
+
return null;
|
|
19087
|
+
}
|
|
19088
|
+
if (duplicate.expiresAt <= Date.now()) {
|
|
19089
|
+
this.duplicateMessages.delete(messageId);
|
|
19090
|
+
return null;
|
|
19091
|
+
}
|
|
19092
|
+
return duplicate.originalMessageId;
|
|
19093
|
+
}
|
|
18637
19094
|
receiveById(messageId, consumerGroup) {
|
|
18638
19095
|
const message2 = this.messages.get(messageId);
|
|
18639
19096
|
if (!message2)
|
|
@@ -18828,6 +19285,16 @@ var QueueBroker = class {
|
|
|
18828
19285
|
}
|
|
18829
19286
|
tick() {
|
|
18830
19287
|
const now = Date.now();
|
|
19288
|
+
for (const [key, record] of this.idempotencyRecords) {
|
|
19289
|
+
if (record.expiresAt <= now) {
|
|
19290
|
+
this.idempotencyRecords.delete(key);
|
|
19291
|
+
}
|
|
19292
|
+
}
|
|
19293
|
+
for (const [messageId, record] of this.duplicateMessages) {
|
|
19294
|
+
if (record.expiresAt <= now) {
|
|
19295
|
+
this.duplicateMessages.delete(messageId);
|
|
19296
|
+
}
|
|
19297
|
+
}
|
|
18831
19298
|
for (const group of this.consumerGroups) {
|
|
18832
19299
|
const groupDeliveries = this.deliveryState.get(group.id);
|
|
18833
19300
|
if (!groupDeliveries)
|
|
@@ -18950,8 +19417,8 @@ function parseListen(str, defaultPort = 3e3) {
|
|
|
18950
19417
|
if (!isNaN(port)) {
|
|
18951
19418
|
return [port];
|
|
18952
19419
|
}
|
|
18953
|
-
const
|
|
18954
|
-
switch (
|
|
19420
|
+
const url4 = parse(str);
|
|
19421
|
+
switch (url4.protocol) {
|
|
18955
19422
|
case "pipe:": {
|
|
18956
19423
|
const cutStr = str.replace(/^pipe:/, "");
|
|
18957
19424
|
if (cutStr.slice(0, 4) !== "\\\\.\\") {
|
|
@@ -18960,25 +19427,25 @@ function parseListen(str, defaultPort = 3e3) {
|
|
|
18960
19427
|
return [cutStr];
|
|
18961
19428
|
}
|
|
18962
19429
|
case "unix:":
|
|
18963
|
-
if (!
|
|
19430
|
+
if (!url4.pathname) {
|
|
18964
19431
|
throw new Error(`Invalid UNIX domain socket endpoint: ${str}`);
|
|
18965
19432
|
}
|
|
18966
|
-
return [
|
|
19433
|
+
return [url4.pathname];
|
|
18967
19434
|
case "tcp:":
|
|
18968
|
-
|
|
18969
|
-
return [parseInt(
|
|
19435
|
+
url4.port = url4.port || String(defaultPort);
|
|
19436
|
+
return [parseInt(url4.port, 10), url4.hostname ?? void 0];
|
|
18970
19437
|
default:
|
|
18971
|
-
if (!
|
|
18972
|
-
if (
|
|
18973
|
-
return [defaultPort,
|
|
19438
|
+
if (!url4.slashes) {
|
|
19439
|
+
if (url4.protocol === null) {
|
|
19440
|
+
return [defaultPort, url4.pathname ?? void 0];
|
|
18974
19441
|
}
|
|
18975
|
-
port = Number(
|
|
18976
|
-
if (
|
|
18977
|
-
return [port,
|
|
19442
|
+
port = Number(url4.hostname);
|
|
19443
|
+
if (url4.protocol && !isNaN(port)) {
|
|
19444
|
+
return [port, url4.protocol.substring(0, url4.protocol.length - 1)];
|
|
18978
19445
|
}
|
|
18979
19446
|
}
|
|
18980
19447
|
throw new Error(
|
|
18981
|
-
`Unknown \`--listen\` scheme (protocol): ${
|
|
19448
|
+
`Unknown \`--listen\` scheme (protocol): ${url4.protocol}`
|
|
18982
19449
|
);
|
|
18983
19450
|
}
|
|
18984
19451
|
}
|
|
@@ -19010,6 +19477,7 @@ var DevCommandExitError = class extends Error {
|
|
|
19010
19477
|
};
|
|
19011
19478
|
var DevServer = class {
|
|
19012
19479
|
constructor(cwd, options) {
|
|
19480
|
+
this.responseTransformsByReq = /* @__PURE__ */ new WeakMap();
|
|
19013
19481
|
this.clearVercelConfigPromise = () => {
|
|
19014
19482
|
this.getVercelConfigPromise = null;
|
|
19015
19483
|
};
|
|
@@ -19050,12 +19518,19 @@ var DevServer = class {
|
|
|
19050
19518
|
/**
|
|
19051
19519
|
* This is the equivalent to now-proxy exit_with_status() function.
|
|
19052
19520
|
*/
|
|
19053
|
-
this.exitWithStatus = async (match, routeResult, phase, req, res, requestId) => {
|
|
19521
|
+
this.exitWithStatus = async (match, routeResult, phase, req, res, requestId, responseTransforms) => {
|
|
19054
19522
|
const { status, headers, dest } = routeResult;
|
|
19055
19523
|
const location = headers["location"] || dest;
|
|
19056
19524
|
if (status && location && 300 <= status && status <= 399) {
|
|
19057
19525
|
output_manager_default.debug(`Route found with redirect status code ${status}`);
|
|
19058
|
-
await this.sendRedirect(
|
|
19526
|
+
await this.sendRedirect(
|
|
19527
|
+
req,
|
|
19528
|
+
res,
|
|
19529
|
+
requestId,
|
|
19530
|
+
location,
|
|
19531
|
+
status,
|
|
19532
|
+
responseTransforms
|
|
19533
|
+
);
|
|
19059
19534
|
return true;
|
|
19060
19535
|
}
|
|
19061
19536
|
if (!match && status && phase !== "miss") {
|
|
@@ -19063,7 +19538,11 @@ var DevServer = class {
|
|
|
19063
19538
|
return false;
|
|
19064
19539
|
}
|
|
19065
19540
|
output_manager_default.debug(`Route found with with status code ${status}`);
|
|
19066
|
-
|
|
19541
|
+
const errorHeaders = { ...headers };
|
|
19542
|
+
if (responseTransforms) {
|
|
19543
|
+
applyResponseTransforms(errorHeaders, responseTransforms);
|
|
19544
|
+
}
|
|
19545
|
+
await this.sendError(req, res, requestId, "", status, errorHeaders);
|
|
19067
19546
|
return true;
|
|
19068
19547
|
}
|
|
19069
19548
|
return false;
|
|
@@ -19094,11 +19573,12 @@ var DevServer = class {
|
|
|
19094
19573
|
const retentionSeconds = retentionHeader && !isNaN(parseInt(retentionHeader, 10)) ? parseInt(retentionHeader, 10) : void 0;
|
|
19095
19574
|
const delayHeader = req.headers["vqs-delay-seconds"];
|
|
19096
19575
|
const delaySeconds = delayHeader && !isNaN(parseInt(delayHeader, 10)) ? parseInt(delayHeader, 10) : void 0;
|
|
19576
|
+
const idempotencyKey = req.headers["vqs-idempotency-key"];
|
|
19097
19577
|
const { messageId } = this.queueBroker.enqueue(
|
|
19098
19578
|
topic,
|
|
19099
19579
|
payload,
|
|
19100
19580
|
contentType2,
|
|
19101
|
-
{ retentionSeconds, delaySeconds }
|
|
19581
|
+
{ retentionSeconds, delaySeconds, idempotencyKey }
|
|
19102
19582
|
);
|
|
19103
19583
|
res.writeHead(201, {
|
|
19104
19584
|
"Content-Type": "application/json",
|
|
@@ -19111,7 +19591,18 @@ var DevServer = class {
|
|
|
19111
19591
|
/^([A-Za-z0-9_-]+)\/consumer\/([A-Za-z0-9_-]+)\/id\/([^/]+)$/
|
|
19112
19592
|
);
|
|
19113
19593
|
if (req.method === "POST" && receiveByIdMatch) {
|
|
19114
|
-
const [, , consumer, messageId] = receiveByIdMatch;
|
|
19594
|
+
const [, queueName, consumer, messageId] = receiveByIdMatch;
|
|
19595
|
+
const originalMessageId = this.queueBroker.getOriginalMessageIdForDuplicate(queueName, messageId);
|
|
19596
|
+
if (originalMessageId) {
|
|
19597
|
+
res.writeHead(409, { "Content-Type": "application/json" });
|
|
19598
|
+
res.end(
|
|
19599
|
+
JSON.stringify({
|
|
19600
|
+
error: "This messageId was a duplicate - use originalMessageId instead",
|
|
19601
|
+
originalMessageId
|
|
19602
|
+
})
|
|
19603
|
+
);
|
|
19604
|
+
return;
|
|
19605
|
+
}
|
|
19115
19606
|
const result = this.queueBroker.receiveById(messageId, consumer);
|
|
19116
19607
|
if (!result) {
|
|
19117
19608
|
res.writeHead(404);
|
|
@@ -19240,7 +19731,7 @@ ${partHeaders}\r
|
|
|
19240
19731
|
*/
|
|
19241
19732
|
this.serveProjectAsNowV2 = async (req, res, requestId, vercelConfig, routes = vercelConfig.routes, callLevel = 0) => {
|
|
19242
19733
|
const { debug } = output_manager_default;
|
|
19243
|
-
const parsed =
|
|
19734
|
+
const parsed = url3.parse(req.url || "/");
|
|
19244
19735
|
if (typeof parsed.pathname === "string" && parsed.pathname.includes("//")) {
|
|
19245
19736
|
let location = parsed.pathname.replace(/\/+/g, "/");
|
|
19246
19737
|
if (parsed.search) {
|
|
@@ -19285,11 +19776,11 @@ ${partHeaders}\r
|
|
|
19285
19776
|
const getReqUrl = (rr) => {
|
|
19286
19777
|
if (rr.dest) {
|
|
19287
19778
|
if (rr.query) {
|
|
19288
|
-
const destParsed =
|
|
19779
|
+
const destParsed = url3.parse(rr.dest);
|
|
19289
19780
|
const destQuery = parseQueryString(destParsed.search);
|
|
19290
19781
|
Object.assign(destQuery, rr.query);
|
|
19291
19782
|
destParsed.search = formatQueryString(destQuery);
|
|
19292
|
-
return
|
|
19783
|
+
return url3.format(destParsed);
|
|
19293
19784
|
}
|
|
19294
19785
|
return rr.dest;
|
|
19295
19786
|
}
|
|
@@ -19307,6 +19798,8 @@ ${partHeaders}\r
|
|
|
19307
19798
|
let prevUrl = req.url;
|
|
19308
19799
|
let prevHeaders = {};
|
|
19309
19800
|
let middlewarePid;
|
|
19801
|
+
const requestTransforms = [];
|
|
19802
|
+
let responseTransforms;
|
|
19310
19803
|
const middleware = [...this.buildMatches.values()].find(
|
|
19311
19804
|
(m) => m.config?.middleware === true
|
|
19312
19805
|
);
|
|
@@ -19412,9 +19905,9 @@ ${partHeaders}\r
|
|
|
19412
19905
|
return;
|
|
19413
19906
|
}
|
|
19414
19907
|
} else {
|
|
19415
|
-
const rewriteUrlParsed =
|
|
19416
|
-
rewriteUrlParsed.search =
|
|
19417
|
-
req.url =
|
|
19908
|
+
const rewriteUrlParsed = url3.parse(beforeRewriteUrl);
|
|
19909
|
+
rewriteUrlParsed.search = url3.parse(rewritePath).search;
|
|
19910
|
+
req.url = url3.format(rewriteUrlParsed);
|
|
19418
19911
|
}
|
|
19419
19912
|
debug(
|
|
19420
19913
|
`Rewrote incoming HTTP URL from "${beforeRewriteUrl}" to "${req.url}"`
|
|
@@ -19458,6 +19951,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19458
19951
|
missRoutes,
|
|
19459
19952
|
phase
|
|
19460
19953
|
);
|
|
19954
|
+
if (routeResult.requestTransforms) {
|
|
19955
|
+
requestTransforms.push(...routeResult.requestTransforms);
|
|
19956
|
+
}
|
|
19957
|
+
if (routeResult.responseTransforms) {
|
|
19958
|
+
responseTransforms = routeResult.responseTransforms;
|
|
19959
|
+
}
|
|
19461
19960
|
if (routeResult.continue) {
|
|
19462
19961
|
if (routeResult.dest) {
|
|
19463
19962
|
prevUrl = getReqUrl(routeResult);
|
|
@@ -19472,15 +19971,18 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19472
19971
|
res,
|
|
19473
19972
|
requestId,
|
|
19474
19973
|
routeResult.matched_route,
|
|
19475
|
-
vercelConfig
|
|
19974
|
+
vercelConfig,
|
|
19975
|
+
requestTransforms,
|
|
19976
|
+
responseTransforms
|
|
19476
19977
|
);
|
|
19477
19978
|
}
|
|
19478
19979
|
if (routeResult.isDestUrl) {
|
|
19479
|
-
const destParsed =
|
|
19980
|
+
const destParsed = url3.parse(routeResult.dest);
|
|
19480
19981
|
const destQuery = parseQueryString(destParsed.search);
|
|
19481
19982
|
Object.assign(destQuery, routeResult.query);
|
|
19482
19983
|
destParsed.search = formatQueryString(destQuery);
|
|
19483
|
-
const destUrl =
|
|
19984
|
+
const destUrl = url3.format(destParsed);
|
|
19985
|
+
this.prepareTransforms(req, requestTransforms, responseTransforms);
|
|
19484
19986
|
debug(`ProxyPass: ${destUrl}`);
|
|
19485
19987
|
this.setResponseHeaders(res, requestId);
|
|
19486
19988
|
return proxyPass(req, res, destUrl, this, requestId);
|
|
@@ -19498,7 +20000,8 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19498
20000
|
phase,
|
|
19499
20001
|
req,
|
|
19500
20002
|
res,
|
|
19501
|
-
requestId
|
|
20003
|
+
requestId,
|
|
20004
|
+
responseTransforms
|
|
19502
20005
|
)) {
|
|
19503
20006
|
return;
|
|
19504
20007
|
}
|
|
@@ -19513,6 +20016,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19513
20016
|
[],
|
|
19514
20017
|
"miss"
|
|
19515
20018
|
);
|
|
20019
|
+
if (routeResult.requestTransforms) {
|
|
20020
|
+
requestTransforms.push(...routeResult.requestTransforms);
|
|
20021
|
+
}
|
|
20022
|
+
if (routeResult.responseTransforms) {
|
|
20023
|
+
responseTransforms = routeResult.responseTransforms;
|
|
20024
|
+
}
|
|
19516
20025
|
match = await findBuildMatch(
|
|
19517
20026
|
this.buildMatches,
|
|
19518
20027
|
this.files,
|
|
@@ -19526,7 +20035,8 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19526
20035
|
phase,
|
|
19527
20036
|
req,
|
|
19528
20037
|
res,
|
|
19529
|
-
requestId
|
|
20038
|
+
requestId,
|
|
20039
|
+
responseTransforms
|
|
19530
20040
|
)) {
|
|
19531
20041
|
return;
|
|
19532
20042
|
}
|
|
@@ -19543,6 +20053,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19543
20053
|
"hit"
|
|
19544
20054
|
);
|
|
19545
20055
|
routeResult.status = prevStatus;
|
|
20056
|
+
if (routeResult.requestTransforms) {
|
|
20057
|
+
requestTransforms.push(...routeResult.requestTransforms);
|
|
20058
|
+
}
|
|
20059
|
+
if (routeResult.responseTransforms) {
|
|
20060
|
+
responseTransforms = routeResult.responseTransforms;
|
|
20061
|
+
}
|
|
19546
20062
|
}
|
|
19547
20063
|
statusCode = routeResult.status;
|
|
19548
20064
|
if (match) {
|
|
@@ -19576,6 +20092,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19576
20092
|
routeResult = routeResultForError;
|
|
19577
20093
|
statusCode = routeResultForError.status;
|
|
19578
20094
|
match = matchForError;
|
|
20095
|
+
if (routeResult.requestTransforms) {
|
|
20096
|
+
requestTransforms.push(...routeResult.requestTransforms);
|
|
20097
|
+
}
|
|
20098
|
+
if (routeResult.responseTransforms) {
|
|
20099
|
+
responseTransforms = routeResult.responseTransforms;
|
|
20100
|
+
}
|
|
19579
20101
|
} else if (matched_route && matched_route.src && !matched_route.dest) {
|
|
19580
20102
|
debug(
|
|
19581
20103
|
"Route without `dest` detected in error phase, attempting to exit early"
|
|
@@ -19586,7 +20108,8 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19586
20108
|
"error",
|
|
19587
20109
|
req,
|
|
19588
20110
|
res,
|
|
19589
|
-
requestId
|
|
20111
|
+
requestId,
|
|
20112
|
+
responseTransforms
|
|
19590
20113
|
)) {
|
|
19591
20114
|
return;
|
|
19592
20115
|
}
|
|
@@ -19618,12 +20141,13 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19618
20141
|
req.headers[name] = value;
|
|
19619
20142
|
}
|
|
19620
20143
|
this.setResponseHeaders(res, requestId);
|
|
19621
|
-
const origUrl =
|
|
20144
|
+
const origUrl = url3.parse(req.url || "/");
|
|
19622
20145
|
const origQuery = parseQueryString(origUrl.search);
|
|
19623
20146
|
origUrl.pathname = dest;
|
|
19624
20147
|
Object.assign(origQuery, query);
|
|
19625
20148
|
origUrl.search = formatQueryString(origQuery);
|
|
19626
|
-
req.url =
|
|
20149
|
+
req.url = url3.format(origUrl);
|
|
20150
|
+
this.prepareTransforms(req, requestTransforms, responseTransforms);
|
|
19627
20151
|
return proxyPass(req, res, upstream, this, requestId, false);
|
|
19628
20152
|
}
|
|
19629
20153
|
if (statusCode === 404 && routeResult.phase === "miss" || !this.renderDirectoryListing(req, res, requestPath, requestId)) {
|
|
@@ -19634,12 +20158,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19634
20158
|
const buildRequestPath = match.buildResults.has(null) ? null : requestPath;
|
|
19635
20159
|
const buildResult = match.buildResults.get(buildRequestPath);
|
|
19636
20160
|
if (buildResult && Array.isArray(buildResult.routes) && buildResult.routes.length > 0) {
|
|
19637
|
-
const origUrl =
|
|
20161
|
+
const origUrl = url3.parse(req.url || "/");
|
|
19638
20162
|
const origQuery = parseQueryString(origUrl.search);
|
|
19639
20163
|
origUrl.pathname = dest;
|
|
19640
20164
|
Object.assign(origQuery, query);
|
|
19641
20165
|
origUrl.search = formatQueryString(origQuery);
|
|
19642
|
-
const newUrl =
|
|
20166
|
+
const newUrl = url3.format(origUrl);
|
|
19643
20167
|
debug(
|
|
19644
20168
|
`Checking build result's ${buildResult.routes.length} \`routes\` to match ${newUrl}`
|
|
19645
20169
|
);
|
|
@@ -19715,11 +20239,11 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19715
20239
|
debug(
|
|
19716
20240
|
`Proxying to "${builderPkg.name}" dev server (port=${port}, pid=${pid})`
|
|
19717
20241
|
);
|
|
19718
|
-
const origUrl =
|
|
20242
|
+
const origUrl = url3.parse(req.url || "/");
|
|
19719
20243
|
const origQuery = parseQueryString(origUrl.search);
|
|
19720
20244
|
Object.assign(origQuery, query);
|
|
19721
20245
|
origUrl.search = formatQueryString(origQuery);
|
|
19722
|
-
req.url =
|
|
20246
|
+
req.url = url3.format({
|
|
19723
20247
|
pathname: origUrl.pathname,
|
|
19724
20248
|
search: origUrl.search
|
|
19725
20249
|
});
|
|
@@ -19727,6 +20251,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19727
20251
|
for (const [name, value] of Object.entries(headers2)) {
|
|
19728
20252
|
req.headers[name] = value;
|
|
19729
20253
|
}
|
|
20254
|
+
this.prepareTransforms(req, requestTransforms, responseTransforms);
|
|
19730
20255
|
this.setResponseHeaders(res, requestId);
|
|
19731
20256
|
return proxyPass(
|
|
19732
20257
|
req,
|
|
@@ -19751,6 +20276,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19751
20276
|
for (const [name, value] of Object.entries(headers2)) {
|
|
19752
20277
|
req.headers[name] = value;
|
|
19753
20278
|
}
|
|
20279
|
+
this.prepareTransforms(req, requestTransforms, responseTransforms);
|
|
19754
20280
|
this.setResponseHeaders(res, requestId);
|
|
19755
20281
|
return proxyPass(req, res, this.devProcessOrigin, this, requestId, false);
|
|
19756
20282
|
}
|
|
@@ -19765,6 +20291,12 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19765
20291
|
switch (asset.type) {
|
|
19766
20292
|
case "FileFsRef":
|
|
19767
20293
|
this.setResponseHeaders(res, requestId);
|
|
20294
|
+
const staticResHeaders = {};
|
|
20295
|
+
applyResponseTransforms(staticResHeaders, responseTransforms ?? []);
|
|
20296
|
+
for (const [name, value] of Object.entries(staticResHeaders)) {
|
|
20297
|
+
if (value !== void 0)
|
|
20298
|
+
res.setHeader(name, value);
|
|
20299
|
+
}
|
|
19768
20300
|
req.url = `/${basename(asset.fsPath)}`;
|
|
19769
20301
|
return serveStaticFile(req, res, dirname2(asset.fsPath), {
|
|
19770
20302
|
headers: [
|
|
@@ -19784,6 +20316,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19784
20316
|
"Content-Length": asset.data.length,
|
|
19785
20317
|
"Content-Type": asset.contentType || getMimeType(assetKey)
|
|
19786
20318
|
};
|
|
20319
|
+
applyResponseTransforms(headers2, responseTransforms ?? []);
|
|
19787
20320
|
this.setResponseHeaders(res, requestId, headers2);
|
|
19788
20321
|
res.end(asset.data);
|
|
19789
20322
|
return;
|
|
@@ -19798,14 +20331,16 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19798
20331
|
return;
|
|
19799
20332
|
}
|
|
19800
20333
|
requestId = generateRequestId(this.podId, true);
|
|
19801
|
-
const origUrl =
|
|
20334
|
+
const origUrl = url3.parse(req.url || "/");
|
|
19802
20335
|
const origQuery = parseQueryString(origUrl.search);
|
|
19803
20336
|
Object.assign(origQuery, query);
|
|
19804
20337
|
origUrl.search = formatQueryString(origQuery);
|
|
19805
|
-
|
|
20338
|
+
req.url = url3.format({
|
|
19806
20339
|
pathname: origUrl.pathname,
|
|
19807
20340
|
search: origUrl.search
|
|
19808
20341
|
});
|
|
20342
|
+
applyRequestTransforms(req, requestTransforms);
|
|
20343
|
+
const path6 = req.url || "/";
|
|
19809
20344
|
const body = await (0, import_raw_body.default)(req);
|
|
19810
20345
|
const payload = {
|
|
19811
20346
|
method: req.method || "GET",
|
|
@@ -19839,7 +20374,9 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19839
20374
|
if (!statusCode) {
|
|
19840
20375
|
res.statusCode = result.statusCode;
|
|
19841
20376
|
}
|
|
19842
|
-
|
|
20377
|
+
const lambdaHeaders = result.headers ?? {};
|
|
20378
|
+
applyResponseTransforms(lambdaHeaders, responseTransforms ?? []);
|
|
20379
|
+
this.setResponseHeaders(res, requestId, lambdaHeaders);
|
|
19843
20380
|
let resBody;
|
|
19844
20381
|
if (result.encoding === "base64" && typeof result.body === "string") {
|
|
19845
20382
|
resBody = Buffer.from(result.body, "base64");
|
|
@@ -19870,8 +20407,13 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
19870
20407
|
ws: true,
|
|
19871
20408
|
xfwd: true
|
|
19872
20409
|
});
|
|
19873
|
-
this.proxy.on("proxyRes", (proxyRes) => {
|
|
20410
|
+
this.proxy.on("proxyRes", (proxyRes, req) => {
|
|
19874
20411
|
proxyRes.headers["server"] = "Vercel";
|
|
20412
|
+
const responseTransforms = this.responseTransformsByReq.get(req);
|
|
20413
|
+
if (responseTransforms) {
|
|
20414
|
+
this.responseTransformsByReq.delete(req);
|
|
20415
|
+
applyResponseTransforms(proxyRes.headers, responseTransforms);
|
|
20416
|
+
}
|
|
19875
20417
|
});
|
|
19876
20418
|
this.proxy.on("error", (err, req, res) => {
|
|
19877
20419
|
output_manager_default.debug(
|
|
@@ -20184,7 +20726,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
20184
20726
|
return void 0;
|
|
20185
20727
|
}
|
|
20186
20728
|
async _getVercelConfig() {
|
|
20187
|
-
const { compileVercelConfig } = await import("../../chunks/compile-vercel-config-
|
|
20729
|
+
const { compileVercelConfig } = await import("../../chunks/compile-vercel-config-7THB6MTJ.js");
|
|
20188
20730
|
await compileVercelConfig(this.cwd);
|
|
20189
20731
|
const configPath = getLocalPathConfig(this.cwd);
|
|
20190
20732
|
const [
|
|
@@ -20207,7 +20749,8 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
20207
20749
|
await this.exit();
|
|
20208
20750
|
}
|
|
20209
20751
|
vercelConfig.routes = maybeRoutes || [];
|
|
20210
|
-
|
|
20752
|
+
const hasResolvedServices = !!this.services && this.services.length > 0;
|
|
20753
|
+
if (!vercelConfig.experimentalServices && !hasResolvedServices && (!vercelConfig.builds || vercelConfig.builds.length === 0)) {
|
|
20211
20754
|
const featHandleMiss = true;
|
|
20212
20755
|
const { projectSettings, cleanUrls, trailingSlash } = vercelConfig;
|
|
20213
20756
|
const files = (await staticFiles(this.cwd, {})).map(
|
|
@@ -20562,7 +21105,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
20562
21105
|
this.server.on("upgrade", async (req, socket, head) => {
|
|
20563
21106
|
await this.startPromise;
|
|
20564
21107
|
if (this.orchestrator) {
|
|
20565
|
-
const pathname2 =
|
|
21108
|
+
const pathname2 = url3.parse(req.url || "/").pathname || "/";
|
|
20566
21109
|
const service = this.orchestrator.getServiceForRoute(pathname2);
|
|
20567
21110
|
if (service) {
|
|
20568
21111
|
const target = `http://${service.host}:${service.port}`;
|
|
@@ -20584,7 +21127,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
|
|
|
20584
21127
|
this.proxy.ws(req, socket, head, { target });
|
|
20585
21128
|
return;
|
|
20586
21129
|
}
|
|
20587
|
-
const pathname =
|
|
21130
|
+
const pathname = url3.parse(req.url || "/").pathname || "/";
|
|
20588
21131
|
for (const match of this.buildMatches.values()) {
|
|
20589
21132
|
const { builder } = match.builderWithPkg;
|
|
20590
21133
|
if ((builder.version === 3 || builder.version === -1) && typeof builder.startDevServer === "function") {
|
|
@@ -20754,10 +21297,14 @@ ${error_code}
|
|
|
20754
21297
|
}
|
|
20755
21298
|
res.end(body);
|
|
20756
21299
|
}
|
|
20757
|
-
async sendRedirect(req, res, requestId, location, statusCode = 302) {
|
|
21300
|
+
async sendRedirect(req, res, requestId, location, statusCode = 302, responseTransforms) {
|
|
20758
21301
|
output_manager_default.debug(`Redirect ${statusCode}: ${location}`);
|
|
20759
21302
|
res.statusCode = statusCode;
|
|
20760
|
-
|
|
21303
|
+
const redirectHeaders = { location };
|
|
21304
|
+
if (responseTransforms) {
|
|
21305
|
+
applyResponseTransforms(redirectHeaders, responseTransforms);
|
|
21306
|
+
}
|
|
21307
|
+
this.setResponseHeaders(res, requestId, redirectHeaders);
|
|
20761
21308
|
let body;
|
|
20762
21309
|
const { accept = "text/plain" } = req.headers;
|
|
20763
21310
|
if (accept.includes("json")) {
|
|
@@ -20796,6 +21343,17 @@ ${error_code}
|
|
|
20796
21343
|
res.setHeader(name, value);
|
|
20797
21344
|
}
|
|
20798
21345
|
}
|
|
21346
|
+
prepareTransforms(req, requestTransforms, responseTransforms) {
|
|
21347
|
+
if (requestTransforms && requestTransforms.length > 0) {
|
|
21348
|
+
applyRequestTransforms(req, requestTransforms);
|
|
21349
|
+
}
|
|
21350
|
+
if (responseTransforms && hasResponseTransforms(responseTransforms)) {
|
|
21351
|
+
this.responseTransformsByReq.set(req, responseTransforms);
|
|
21352
|
+
}
|
|
21353
|
+
}
|
|
21354
|
+
clearResponseTransforms(req) {
|
|
21355
|
+
this.responseTransformsByReq.delete(req);
|
|
21356
|
+
}
|
|
20799
21357
|
/**
|
|
20800
21358
|
* Returns the request `headers` that will be sent to the Lambda.
|
|
20801
21359
|
*/
|
|
@@ -20842,7 +21400,7 @@ ${error_code}
|
|
|
20842
21400
|
}
|
|
20843
21401
|
return this.serviceRoutesTable.get(serviceName) || [];
|
|
20844
21402
|
}
|
|
20845
|
-
async delegateToService(req, res, requestId, matchedRoute, vercelConfig) {
|
|
21403
|
+
async delegateToService(req, res, requestId, matchedRoute, vercelConfig, requestTransforms, responseTransforms) {
|
|
20846
21404
|
const { debug } = output_manager_default;
|
|
20847
21405
|
const { service: serviceName, path: destPath } = matchedRoute.destination;
|
|
20848
21406
|
const origin = this.orchestrator?.getServiceOrigin(serviceName);
|
|
@@ -20859,7 +21417,7 @@ ${error_code}
|
|
|
20859
21417
|
);
|
|
20860
21418
|
return;
|
|
20861
21419
|
}
|
|
20862
|
-
const parsed =
|
|
21420
|
+
const parsed = url3.parse(req.url || "/");
|
|
20863
21421
|
const originalPathname = parsed.pathname || "/";
|
|
20864
21422
|
let lookupPath = originalPathname;
|
|
20865
21423
|
if (typeof destPath === "string" && matchedRoute.src) {
|
|
@@ -20873,6 +21431,10 @@ ${error_code}
|
|
|
20873
21431
|
}
|
|
20874
21432
|
const serviceRoutes = this.getServiceRouteTable(serviceName);
|
|
20875
21433
|
const proxyHeaders = this.getProxyHeaders(req, requestId, false);
|
|
21434
|
+
const requestTransformsToApply = [
|
|
21435
|
+
...requestTransforms ?? []
|
|
21436
|
+
];
|
|
21437
|
+
let responseTransformsToApply = responseTransforms;
|
|
20876
21438
|
if (serviceRoutes.length > 0) {
|
|
20877
21439
|
const serviceResult = await devRouter(
|
|
20878
21440
|
`${lookupPath}${parsed.search || ""}`,
|
|
@@ -20881,6 +21443,12 @@ ${error_code}
|
|
|
20881
21443
|
this,
|
|
20882
21444
|
vercelConfig
|
|
20883
21445
|
);
|
|
21446
|
+
if (serviceResult.requestTransforms) {
|
|
21447
|
+
requestTransformsToApply.push(...serviceResult.requestTransforms);
|
|
21448
|
+
}
|
|
21449
|
+
if (serviceResult.responseTransforms) {
|
|
21450
|
+
responseTransformsToApply = serviceResult.responseTransforms;
|
|
21451
|
+
}
|
|
20884
21452
|
const location = serviceResult.headers?.location;
|
|
20885
21453
|
if (location && typeof serviceResult.status === "number" && serviceResult.status >= 300 && serviceResult.status < 400) {
|
|
20886
21454
|
await this.sendRedirect(
|
|
@@ -20888,7 +21456,8 @@ ${error_code}
|
|
|
20888
21456
|
res,
|
|
20889
21457
|
requestId,
|
|
20890
21458
|
location,
|
|
20891
|
-
serviceResult.status
|
|
21459
|
+
serviceResult.status,
|
|
21460
|
+
responseTransformsToApply
|
|
20892
21461
|
);
|
|
20893
21462
|
return;
|
|
20894
21463
|
}
|
|
@@ -20903,6 +21472,11 @@ ${error_code}
|
|
|
20903
21472
|
for (const [name, value] of Object.entries(proxyHeaders)) {
|
|
20904
21473
|
req.headers[name] = value;
|
|
20905
21474
|
}
|
|
21475
|
+
this.prepareTransforms(
|
|
21476
|
+
req,
|
|
21477
|
+
requestTransformsToApply,
|
|
21478
|
+
responseTransformsToApply
|
|
21479
|
+
);
|
|
20906
21480
|
this.setResponseHeaders(res, requestId);
|
|
20907
21481
|
debug(`Delegating to service "${serviceName}": ${origin}`);
|
|
20908
21482
|
return proxyPass(req, res, origin, this, requestId, false);
|
|
@@ -21128,6 +21702,7 @@ function proxyPass(req, res, dest, devServer, requestId, ignorePath = true) {
|
|
|
21128
21702
|
res,
|
|
21129
21703
|
{ target: dest, ignorePath },
|
|
21130
21704
|
(error2) => {
|
|
21705
|
+
devServer.clearResponseTransforms(req);
|
|
21131
21706
|
output_manager_default.debug(`Failed to complete request to ${req.url}: ${error2}`);
|
|
21132
21707
|
if (!res.headersSent) {
|
|
21133
21708
|
devServer.sendError(req, res, requestId, "FUNCTION_INVOCATION_FAILED");
|
|
@@ -21319,11 +21894,6 @@ var import_ms5 = __toESM(require_ms(), 1);
|
|
|
21319
21894
|
import { setTimeout as setTimeout2 } from "timers/promises";
|
|
21320
21895
|
import { decodeJwt } from "jose";
|
|
21321
21896
|
import { performance } from "perf_hooks";
|
|
21322
|
-
|
|
21323
|
-
// src/util/env/constants.ts
|
|
21324
|
-
var VERCEL_OIDC_TOKEN = "VERCEL_OIDC_TOKEN";
|
|
21325
|
-
|
|
21326
|
-
// src/util/env/refresh-oidc-token.ts
|
|
21327
21897
|
var REFRESH_BEFORE_EXPIRY_MILLIS = getMs(
|
|
21328
21898
|
(0, import_ms5.default)("15m"),
|
|
21329
21899
|
process.env.REFRESH_VERCEL_OIDC_TOKEN_BEFORE_EXPIRY_MILLIS
|