@vercel/next 2.7.9 → 2.8.66

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.
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /// <reference lib="DOM" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const to_plain_headers_1 = require("./to-plain-headers");
5
+ /**
6
+ * A template to adapt the Next.js Edge Function signature into the core Edge
7
+ * Function signature. This will automatically inject parameters that are
8
+ * missing in default Edge Functions from the provided configuration
9
+ * parameters. Static and Dynamic RegExp are calculated in the module scope
10
+ * to avoid recomputing them for each function invocation.
11
+ */
12
+ function getNextjsEdgeFunction(params) {
13
+ var _a;
14
+ const staticRoutes = params.staticRoutes.map(route => ({
15
+ regexp: new RegExp(route.namedRegex),
16
+ page: route.page,
17
+ }));
18
+ const dynamicRoutes = ((_a = params.dynamicRoutes) === null || _a === void 0 ? void 0 : _a.map(route => ({
19
+ regexp: new RegExp(route.namedRegex),
20
+ page: route.page,
21
+ }))) || [];
22
+ return async function edgeFunction(request, context) {
23
+ var _a, _b;
24
+ let pathname = new URL(request.url).pathname;
25
+ let pageMatch = {};
26
+ // Remove the basePath from the URL
27
+ if ((_a = params.nextConfig) === null || _a === void 0 ? void 0 : _a.basePath) {
28
+ if (pathname.startsWith(params.nextConfig.basePath)) {
29
+ pathname = pathname.replace(params.nextConfig.basePath, '') || '/';
30
+ }
31
+ }
32
+ // Remove the locale from the URL
33
+ if ((_b = params.nextConfig) === null || _b === void 0 ? void 0 : _b.i18n) {
34
+ for (const locale of params.nextConfig.i18n.locales) {
35
+ const regexp = new RegExp(`^/${locale}($|/)`, 'i');
36
+ if (pathname.match(regexp)) {
37
+ pathname = pathname.replace(regexp, '/') || '/';
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ // Find the page match that will happen if there are no assets matching
43
+ for (const route of staticRoutes) {
44
+ const result = route.regexp.exec(pathname);
45
+ if (result) {
46
+ pageMatch.name = route.page;
47
+ break;
48
+ }
49
+ }
50
+ if (!pageMatch.name) {
51
+ const isApi = isApiRoute(pathname);
52
+ for (const route of dynamicRoutes || []) {
53
+ /**
54
+ * Dynamic API routes should not be checked against dynamic non API
55
+ * routes so we skip it in such case. For example, a request to
56
+ * /api/test should not match /pages/[slug].test having:
57
+ * - pages/api/foo.js
58
+ * - pages/[slug]/test.js
59
+ */
60
+ if (isApi && !isApiRoute(route.page)) {
61
+ continue;
62
+ }
63
+ const result = route.regexp.exec(pathname);
64
+ if (result) {
65
+ pageMatch = {
66
+ name: route.page,
67
+ params: result.groups,
68
+ };
69
+ break;
70
+ }
71
+ }
72
+ }
73
+ // Invoke the function injecting missing parameters
74
+ const result = await _ENTRIES[`middleware_${params.name}`].default.call({}, {
75
+ request: {
76
+ url: request.url,
77
+ method: request.method,
78
+ headers: (0, to_plain_headers_1.toPlainHeaders)(request.headers),
79
+ ip: header(request.headers, IncomingHeaders.Ip),
80
+ geo: {
81
+ city: header(request.headers, IncomingHeaders.City, true),
82
+ country: header(request.headers, IncomingHeaders.Country, true),
83
+ latitude: header(request.headers, IncomingHeaders.Latitude),
84
+ longitude: header(request.headers, IncomingHeaders.Longitude),
85
+ region: header(request.headers, IncomingHeaders.Region, true),
86
+ },
87
+ nextConfig: params.nextConfig,
88
+ page: pageMatch,
89
+ body: request.body,
90
+ },
91
+ });
92
+ context.waitUntil(result.waitUntil);
93
+ return result.response;
94
+ };
95
+ }
96
+ exports.default = getNextjsEdgeFunction;
97
+ /**
98
+ * Allows to get a header value by name but falling back to `undefined` when
99
+ * the value does not exist. Optionally, we can make this function decode
100
+ * what it reads for certain cases.
101
+ *
102
+ * @param headers The Headers object.
103
+ * @param name The name of the header to extract.
104
+ * @param decode Tells if we should decode the value.
105
+ * @returns The header value or undefined.
106
+ */
107
+ function header(headers, name, decode = false) {
108
+ const value = headers.get(name) || undefined;
109
+ return decode && value ? decodeURIComponent(value) : value;
110
+ }
111
+ function isApiRoute(path) {
112
+ return path === '/api' || path.startsWith('/api/');
113
+ }
114
+ var IncomingHeaders;
115
+ (function (IncomingHeaders) {
116
+ /**
117
+ * City of the original client IP calculated by Vercel Proxy.
118
+ */
119
+ IncomingHeaders["City"] = "x-vercel-ip-city";
120
+ /**
121
+ * Country of the original client IP calculated by Vercel Proxy.
122
+ */
123
+ IncomingHeaders["Country"] = "x-vercel-ip-country";
124
+ /**
125
+ * Ip from Vercel Proxy. Do not confuse it with the client Ip.
126
+ */
127
+ IncomingHeaders["Ip"] = "x-real-ip";
128
+ /**
129
+ * Latitude of the original client IP calculated by Vercel Proxy.
130
+ */
131
+ IncomingHeaders["Latitude"] = "x-vercel-ip-latitude";
132
+ /**
133
+ * Longitude of the original client IP calculated by Vercel Proxy.
134
+ */
135
+ IncomingHeaders["Longitude"] = "x-vercel-ip-longitude";
136
+ /**
137
+ * Region of the original client IP calculated by Vercel Proxy.
138
+ */
139
+ IncomingHeaders["Region"] = "x-vercel-ip-country-region";
140
+ })(IncomingHeaders || (IncomingHeaders = {}));
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.splitCookiesString = exports.toPlainHeaders = void 0;
4
+ /**
5
+ * Transforms a standard Headers object into a plean Headers object. This is
6
+ * done to support a plain format for headers which is used in the Edge
7
+ * Function signature.
8
+ *
9
+ * @param headers Headers from the original request.
10
+ * @returns The same headers formatted as Node Headers.
11
+ */
12
+ function toPlainHeaders(headers) {
13
+ const result = {};
14
+ if (!headers)
15
+ return result;
16
+ headers.forEach((value, key) => {
17
+ result[key] = value;
18
+ if (key.toLowerCase() === 'set-cookie') {
19
+ result[key] = splitCookiesString(value);
20
+ }
21
+ });
22
+ return result;
23
+ }
24
+ exports.toPlainHeaders = toPlainHeaders;
25
+ /**
26
+ * Set-Cookie header field-values are sometimes comma joined in one string.
27
+ * This splits them without choking on commas that are within a single
28
+ * set-cookie field-value, such as in the Expires portion. This is uncommon,
29
+ * but explicitly allowed (https://tools.ietf.org/html/rfc2616#section-4.2)
30
+ */
31
+ function splitCookiesString(cookiesString) {
32
+ const cookiesStrings = [];
33
+ let pos = 0;
34
+ let start;
35
+ let ch;
36
+ let lastComma;
37
+ let nextStart;
38
+ let cookiesSeparatorFound;
39
+ function skipWhitespace() {
40
+ while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos)))
41
+ pos += 1;
42
+ return pos < cookiesString.length;
43
+ }
44
+ function notSpecialChar() {
45
+ ch = cookiesString.charAt(pos);
46
+ return ch !== '=' && ch !== ';' && ch !== ',';
47
+ }
48
+ while (pos < cookiesString.length) {
49
+ start = pos;
50
+ cookiesSeparatorFound = false;
51
+ while (skipWhitespace()) {
52
+ ch = cookiesString.charAt(pos);
53
+ if (ch === ',') {
54
+ // ',' is a cookie separator if we have later first '=', not ';' or ','
55
+ lastComma = pos;
56
+ pos += 1;
57
+ skipWhitespace();
58
+ nextStart = pos;
59
+ while (pos < cookiesString.length && notSpecialChar()) {
60
+ pos += 1;
61
+ }
62
+ // currently special character
63
+ if (pos < cookiesString.length && cookiesString.charAt(pos) === '=') {
64
+ // we found cookies separator
65
+ cookiesSeparatorFound = true;
66
+ // pos is inside the next cookie, so back up and return it.
67
+ pos = nextStart;
68
+ cookiesStrings.push(cookiesString.substring(start, lastComma));
69
+ start = pos;
70
+ }
71
+ else {
72
+ // in param ',' or param separator ';',
73
+ // we continue from that comma
74
+ pos = lastComma + 1;
75
+ }
76
+ }
77
+ else {
78
+ pos += 1;
79
+ }
80
+ }
81
+ if (!cookiesSeparatorFound || pos >= cookiesString.length) {
82
+ cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
83
+ }
84
+ }
85
+ return cookiesStrings;
86
+ }
87
+ exports.splitCookiesString = splitCookiesString;