@vercel/routing-utils 2.2.1 → 3.1.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.
@@ -1,340 +1,352 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.collectHasSegments = exports.sourceToRegex = exports.convertTrailingSlash = exports.convertHeaders = exports.convertRewrites = exports.convertRedirects = exports.convertCleanUrls = exports.getCleanUrls = void 0;
4
- /**
5
- * This converts Superstatic configuration to vercel.json Routes
6
- * See https://github.com/firebase/superstatic#configuration
7
- */
8
- const url_1 = require("url");
9
- const path_to_regexp_1 = require("path-to-regexp");
10
- const UN_NAMED_SEGMENT = '__UN_NAMED_SEGMENT__';
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var superstatic_exports = {};
20
+ __export(superstatic_exports, {
21
+ collectHasSegments: () => collectHasSegments,
22
+ convertCleanUrls: () => convertCleanUrls,
23
+ convertHeaders: () => convertHeaders,
24
+ convertRedirects: () => convertRedirects,
25
+ convertRewrites: () => convertRewrites,
26
+ convertTrailingSlash: () => convertTrailingSlash,
27
+ getCleanUrls: () => getCleanUrls,
28
+ sourceToRegex: () => sourceToRegex
29
+ });
30
+ module.exports = __toCommonJS(superstatic_exports);
31
+ var import_url = require("url");
32
+ var import_path_to_regexp = require("path-to-regexp");
33
+ const UN_NAMED_SEGMENT = "__UN_NAMED_SEGMENT__";
11
34
  function getCleanUrls(filePaths) {
12
- const htmlFiles = filePaths
13
- .map(toRoute)
14
- .filter(f => f.endsWith('.html'))
15
- .map(f => ({
16
- html: f,
17
- clean: f.slice(0, -5),
18
- }));
19
- return htmlFiles;
35
+ const htmlFiles = filePaths.map(toRoute).filter((f) => f.endsWith(".html")).map((f) => ({
36
+ html: f,
37
+ clean: f.slice(0, -5)
38
+ }));
39
+ return htmlFiles;
20
40
  }
21
- exports.getCleanUrls = getCleanUrls;
22
41
  function convertCleanUrls(cleanUrls, trailingSlash, status = 308) {
23
- const routes = [];
24
- if (cleanUrls) {
25
- const loc = trailingSlash ? '/$1/' : '/$1';
26
- routes.push({
27
- src: '^/(?:(.+)/)?index(?:\\.html)?/?$',
28
- headers: { Location: loc },
29
- status,
30
- });
31
- routes.push({
32
- src: '^/(.*)\\.html/?$',
33
- headers: { Location: loc },
34
- status,
35
- });
36
- }
37
- return routes;
42
+ const routes = [];
43
+ if (cleanUrls) {
44
+ const loc = trailingSlash ? "/$1/" : "/$1";
45
+ routes.push({
46
+ src: "^/(?:(.+)/)?index(?:\\.html)?/?$",
47
+ headers: { Location: loc },
48
+ status
49
+ });
50
+ routes.push({
51
+ src: "^/(.*)\\.html/?$",
52
+ headers: { Location: loc },
53
+ status
54
+ });
55
+ }
56
+ return routes;
38
57
  }
39
- exports.convertCleanUrls = convertCleanUrls;
40
58
  function convertRedirects(redirects, defaultStatus = 308) {
41
- return redirects.map(r => {
42
- const { src, segments } = sourceToRegex(r.source);
43
- const hasSegments = collectHasSegments(r.has);
44
- normalizeHasKeys(r.has);
45
- normalizeHasKeys(r.missing);
46
- try {
47
- const loc = replaceSegments(segments, hasSegments, r.destination, true);
48
- let status;
49
- if (typeof r.permanent === 'boolean') {
50
- status = r.permanent ? 308 : 307;
51
- }
52
- else if (r.statusCode) {
53
- status = r.statusCode;
54
- }
55
- else {
56
- status = defaultStatus;
57
- }
58
- const route = {
59
- src,
60
- headers: { Location: loc },
61
- status,
62
- };
63
- if (r.has) {
64
- route.has = r.has;
65
- }
66
- if (r.missing) {
67
- route.missing = r.missing;
68
- }
69
- return route;
70
- }
71
- catch (e) {
72
- throw new Error(`Failed to parse redirect: ${JSON.stringify(r)}`);
73
- }
74
- });
59
+ return redirects.map((r) => {
60
+ const { src, segments } = sourceToRegex(r.source);
61
+ const hasSegments = collectHasSegments(r.has);
62
+ normalizeHasKeys(r.has);
63
+ normalizeHasKeys(r.missing);
64
+ try {
65
+ const loc = replaceSegments(segments, hasSegments, r.destination, true);
66
+ let status;
67
+ if (typeof r.permanent === "boolean") {
68
+ status = r.permanent ? 308 : 307;
69
+ } else if (r.statusCode) {
70
+ status = r.statusCode;
71
+ } else {
72
+ status = defaultStatus;
73
+ }
74
+ const route = {
75
+ src,
76
+ headers: { Location: loc },
77
+ status
78
+ };
79
+ if (r.has) {
80
+ route.has = r.has;
81
+ }
82
+ if (r.missing) {
83
+ route.missing = r.missing;
84
+ }
85
+ return route;
86
+ } catch (e) {
87
+ throw new Error(`Failed to parse redirect: ${JSON.stringify(r)}`);
88
+ }
89
+ });
75
90
  }
76
- exports.convertRedirects = convertRedirects;
77
91
  function convertRewrites(rewrites, internalParamNames) {
78
- return rewrites.map(r => {
79
- const { src, segments } = sourceToRegex(r.source);
80
- const hasSegments = collectHasSegments(r.has);
81
- normalizeHasKeys(r.has);
82
- normalizeHasKeys(r.missing);
83
- try {
84
- const dest = replaceSegments(segments, hasSegments, r.destination, false, internalParamNames);
85
- const route = { src, dest, check: true };
86
- if (r.has) {
87
- route.has = r.has;
88
- }
89
- if (r.missing) {
90
- route.missing = r.missing;
91
- }
92
- return route;
93
- }
94
- catch (e) {
95
- throw new Error(`Failed to parse rewrite: ${JSON.stringify(r)}`);
96
- }
97
- });
92
+ return rewrites.map((r) => {
93
+ const { src, segments } = sourceToRegex(r.source);
94
+ const hasSegments = collectHasSegments(r.has);
95
+ normalizeHasKeys(r.has);
96
+ normalizeHasKeys(r.missing);
97
+ try {
98
+ const dest = replaceSegments(
99
+ segments,
100
+ hasSegments,
101
+ r.destination,
102
+ false,
103
+ internalParamNames
104
+ );
105
+ const route = { src, dest, check: true };
106
+ if (r.has) {
107
+ route.has = r.has;
108
+ }
109
+ if (r.missing) {
110
+ route.missing = r.missing;
111
+ }
112
+ if (r.statusCode) {
113
+ route.status = r.statusCode;
114
+ }
115
+ return route;
116
+ } catch (e) {
117
+ throw new Error(`Failed to parse rewrite: ${JSON.stringify(r)}`);
118
+ }
119
+ });
98
120
  }
99
- exports.convertRewrites = convertRewrites;
100
121
  function convertHeaders(headers) {
101
- return headers.map(h => {
102
- const obj = {};
103
- const { src, segments } = sourceToRegex(h.source);
104
- const hasSegments = collectHasSegments(h.has);
105
- normalizeHasKeys(h.has);
106
- normalizeHasKeys(h.missing);
107
- const namedSegments = segments.filter(name => name !== UN_NAMED_SEGMENT);
108
- const indexes = {};
109
- segments.forEach((name, index) => {
110
- indexes[name] = toSegmentDest(index);
111
- });
112
- hasSegments.forEach(name => {
113
- indexes[name] = '$' + name;
114
- });
115
- h.headers.forEach(({ key, value }) => {
116
- if (namedSegments.length > 0 || hasSegments.length > 0) {
117
- if (key.includes(':')) {
118
- key = safelyCompile(key, indexes);
119
- }
120
- if (value.includes(':')) {
121
- value = safelyCompile(value, indexes);
122
- }
123
- }
124
- obj[key] = value;
125
- });
126
- const route = {
127
- src,
128
- headers: obj,
129
- continue: true,
130
- };
131
- if (h.has) {
132
- route.has = h.has;
122
+ return headers.map((h) => {
123
+ const obj = {};
124
+ const { src, segments } = sourceToRegex(h.source);
125
+ const hasSegments = collectHasSegments(h.has);
126
+ normalizeHasKeys(h.has);
127
+ normalizeHasKeys(h.missing);
128
+ const namedSegments = segments.filter((name) => name !== UN_NAMED_SEGMENT);
129
+ const indexes = {};
130
+ segments.forEach((name, index) => {
131
+ indexes[name] = toSegmentDest(index);
132
+ });
133
+ hasSegments.forEach((name) => {
134
+ indexes[name] = "$" + name;
135
+ });
136
+ h.headers.forEach(({ key, value }) => {
137
+ if (namedSegments.length > 0 || hasSegments.length > 0) {
138
+ if (key.includes(":")) {
139
+ key = safelyCompile(key, indexes);
133
140
  }
134
- if (h.missing) {
135
- route.missing = h.missing;
141
+ if (value.includes(":")) {
142
+ value = safelyCompile(value, indexes);
136
143
  }
137
- return route;
144
+ }
145
+ obj[key] = value;
138
146
  });
139
- }
140
- exports.convertHeaders = convertHeaders;
141
- function convertTrailingSlash(enable, status = 308) {
142
- const routes = [];
143
- if (enable) {
144
- routes.push({
145
- src: '^/\\.well-known(?:/.*)?$',
146
- });
147
- routes.push({
148
- src: '^/((?:[^/]+/)*[^/\\.]+)$',
149
- headers: { Location: '/$1/' },
150
- status,
151
- });
152
- routes.push({
153
- src: '^/((?:[^/]+/)*[^/]+\\.\\w+)/$',
154
- headers: { Location: '/$1' },
155
- status,
156
- });
147
+ const route = {
148
+ src,
149
+ headers: obj,
150
+ continue: true
151
+ };
152
+ if (h.has) {
153
+ route.has = h.has;
157
154
  }
158
- else {
159
- routes.push({
160
- src: '^/(.*)\\/$',
161
- headers: { Location: '/$1' },
162
- status,
163
- });
155
+ if (h.missing) {
156
+ route.missing = h.missing;
164
157
  }
165
- return routes;
158
+ return route;
159
+ });
166
160
  }
167
- exports.convertTrailingSlash = convertTrailingSlash;
168
- function sourceToRegex(source) {
169
- const keys = [];
170
- const r = (0, path_to_regexp_1.pathToRegexp)(source, keys, {
171
- strict: true,
172
- sensitive: true,
173
- delimiter: '/',
161
+ function convertTrailingSlash(enable, status = 308) {
162
+ const routes = [];
163
+ if (enable) {
164
+ routes.push({
165
+ src: "^/\\.well-known(?:/.*)?$"
174
166
  });
175
- const segments = keys
176
- .map(k => k.name)
177
- .map(name => {
178
- if (typeof name !== 'string') {
179
- return UN_NAMED_SEGMENT;
180
- }
181
- return name;
167
+ routes.push({
168
+ src: "^/((?:[^/]+/)*[^/\\.]+)$",
169
+ headers: { Location: "/$1/" },
170
+ status
171
+ });
172
+ routes.push({
173
+ src: "^/((?:[^/]+/)*[^/]+\\.\\w+)/$",
174
+ headers: { Location: "/$1" },
175
+ status
182
176
  });
183
- return { src: r.source, segments };
177
+ } else {
178
+ routes.push({
179
+ src: "^/(.*)\\/$",
180
+ headers: { Location: "/$1" },
181
+ status
182
+ });
183
+ }
184
+ return routes;
185
+ }
186
+ function sourceToRegex(source) {
187
+ const keys = [];
188
+ const r = (0, import_path_to_regexp.pathToRegexp)(source, keys, {
189
+ strict: true,
190
+ sensitive: true,
191
+ delimiter: "/"
192
+ });
193
+ const segments = keys.map((k) => k.name).map((name) => {
194
+ if (typeof name !== "string") {
195
+ return UN_NAMED_SEGMENT;
196
+ }
197
+ return name;
198
+ });
199
+ return { src: r.source, segments };
184
200
  }
185
- exports.sourceToRegex = sourceToRegex;
186
201
  const namedGroupsRegex = /\(\?<([a-zA-Z][a-zA-Z0-9]*)>/g;
187
202
  const normalizeHasKeys = (hasItems = []) => {
188
- for (const hasItem of hasItems) {
189
- if ('key' in hasItem && hasItem.type === 'header') {
190
- hasItem.key = hasItem.key.toLowerCase();
191
- }
203
+ for (const hasItem of hasItems) {
204
+ if ("key" in hasItem && hasItem.type === "header") {
205
+ hasItem.key = hasItem.key.toLowerCase();
192
206
  }
193
- return hasItems;
207
+ }
208
+ return hasItems;
194
209
  };
195
210
  function collectHasSegments(has) {
196
- const hasSegments = new Set();
197
- for (const hasItem of has || []) {
198
- if (!hasItem.value && 'key' in hasItem) {
199
- hasSegments.add(hasItem.key);
200
- }
201
- if (hasItem.value) {
202
- for (const match of hasItem.value.matchAll(namedGroupsRegex)) {
203
- if (match[1]) {
204
- hasSegments.add(match[1]);
205
- }
206
- }
207
- if (hasItem.type === 'host') {
208
- hasSegments.add('host');
209
- }
211
+ const hasSegments = /* @__PURE__ */ new Set();
212
+ for (const hasItem of has || []) {
213
+ if (!hasItem.value && "key" in hasItem) {
214
+ hasSegments.add(hasItem.key);
215
+ }
216
+ if (hasItem.value) {
217
+ for (const match of hasItem.value.matchAll(namedGroupsRegex)) {
218
+ if (match[1]) {
219
+ hasSegments.add(match[1]);
210
220
  }
221
+ }
222
+ if (hasItem.type === "host") {
223
+ hasSegments.add("host");
224
+ }
211
225
  }
212
- return [...hasSegments];
226
+ }
227
+ return [...hasSegments];
213
228
  }
214
- exports.collectHasSegments = collectHasSegments;
215
- const escapeSegment = (str, segmentName) => str.replace(new RegExp(`:${segmentName}`, 'g'), `__ESC_COLON_${segmentName}`);
216
- const unescapeSegments = (str) => str.replace(/__ESC_COLON_/gi, ':');
229
+ const escapeSegment = (str, segmentName) => str.replace(new RegExp(`:${segmentName}`, "g"), `__ESC_COLON_${segmentName}`);
230
+ const unescapeSegments = (str) => str.replace(/__ESC_COLON_/gi, ":");
217
231
  function replaceSegments(segments, hasItemSegments, destination, isRedirect, internalParamNames) {
218
- const namedSegments = segments.filter(name => name !== UN_NAMED_SEGMENT);
219
- const canNeedReplacing = (destination.includes(':') && namedSegments.length > 0) ||
220
- hasItemSegments.length > 0 ||
221
- !isRedirect;
222
- if (!canNeedReplacing) {
223
- return destination;
224
- }
225
- let escapedDestination = destination;
226
- const indexes = {};
227
- segments.forEach((name, index) => {
228
- indexes[name] = toSegmentDest(index);
229
- escapedDestination = escapeSegment(escapedDestination, name);
230
- });
231
- // 'has' matches override 'source' matches
232
- hasItemSegments.forEach(name => {
233
- indexes[name] = '$' + name;
234
- escapedDestination = escapeSegment(escapedDestination, name);
235
- });
236
- const parsedDestination = (0, url_1.parse)(escapedDestination, true);
237
- delete parsedDestination.href;
238
- delete parsedDestination.path;
239
- delete parsedDestination.search;
240
- delete parsedDestination.host;
241
- // eslint-disable-next-line prefer-const
242
- let { pathname, hash, query, hostname, ...rest } = parsedDestination;
243
- pathname = unescapeSegments(pathname || '');
244
- hash = unescapeSegments(hash || '');
245
- hostname = unescapeSegments(hostname || '');
246
- let destParams = new Set();
247
- const pathnameKeys = [];
248
- const hashKeys = [];
249
- const hostnameKeys = [];
250
- try {
251
- (0, path_to_regexp_1.pathToRegexp)(pathname, pathnameKeys);
252
- (0, path_to_regexp_1.pathToRegexp)(hash || '', hashKeys);
253
- (0, path_to_regexp_1.pathToRegexp)(hostname || '', hostnameKeys);
254
- }
255
- catch (_) {
256
- // this is not fatal so don't error when failing to parse the
257
- // params from the destination
258
- }
259
- destParams = new Set([...pathnameKeys, ...hashKeys, ...hostnameKeys]
260
- .map(key => key.name)
261
- .filter(val => typeof val === 'string'));
262
- pathname = safelyCompile(pathname, indexes, true);
263
- hash = hash ? safelyCompile(hash, indexes, true) : null;
264
- hostname = hostname ? safelyCompile(hostname, indexes, true) : null;
265
- for (const [key, strOrArray] of Object.entries(query)) {
266
- if (Array.isArray(strOrArray)) {
267
- query[key] = strOrArray.map(str => safelyCompile(unescapeSegments(str), indexes, true));
268
- }
269
- else {
270
- // TODO: handle strOrArray is undefined
271
- query[key] = safelyCompile(unescapeSegments(strOrArray), indexes, true);
272
- }
232
+ const namedSegments = segments.filter((name) => name !== UN_NAMED_SEGMENT);
233
+ const canNeedReplacing = destination.includes(":") && namedSegments.length > 0 || hasItemSegments.length > 0 || !isRedirect;
234
+ if (!canNeedReplacing) {
235
+ return destination;
236
+ }
237
+ let escapedDestination = destination;
238
+ const indexes = {};
239
+ segments.forEach((name, index) => {
240
+ indexes[name] = toSegmentDest(index);
241
+ escapedDestination = escapeSegment(escapedDestination, name);
242
+ });
243
+ hasItemSegments.forEach((name) => {
244
+ indexes[name] = "$" + name;
245
+ escapedDestination = escapeSegment(escapedDestination, name);
246
+ });
247
+ const parsedDestination = (0, import_url.parse)(escapedDestination, true);
248
+ delete parsedDestination.href;
249
+ delete parsedDestination.path;
250
+ delete parsedDestination.search;
251
+ delete parsedDestination.host;
252
+ let { pathname, hash, query, hostname, ...rest } = parsedDestination;
253
+ pathname = unescapeSegments(pathname || "");
254
+ hash = unescapeSegments(hash || "");
255
+ hostname = unescapeSegments(hostname || "");
256
+ let destParams = /* @__PURE__ */ new Set();
257
+ const pathnameKeys = [];
258
+ const hashKeys = [];
259
+ const hostnameKeys = [];
260
+ try {
261
+ (0, import_path_to_regexp.pathToRegexp)(pathname, pathnameKeys);
262
+ (0, import_path_to_regexp.pathToRegexp)(hash || "", hashKeys);
263
+ (0, import_path_to_regexp.pathToRegexp)(hostname || "", hostnameKeys);
264
+ } catch (_) {
265
+ }
266
+ destParams = new Set(
267
+ [...pathnameKeys, ...hashKeys, ...hostnameKeys].map((key) => key.name).filter((val) => typeof val === "string")
268
+ );
269
+ pathname = safelyCompile(pathname, indexes, true);
270
+ hash = hash ? safelyCompile(hash, indexes, true) : null;
271
+ hostname = hostname ? safelyCompile(hostname, indexes, true) : null;
272
+ for (const [key, strOrArray] of Object.entries(query)) {
273
+ if (Array.isArray(strOrArray)) {
274
+ query[key] = strOrArray.map(
275
+ (str) => safelyCompile(unescapeSegments(str), indexes, true)
276
+ );
277
+ } else {
278
+ query[key] = safelyCompile(
279
+ unescapeSegments(strOrArray),
280
+ indexes,
281
+ true
282
+ );
273
283
  }
274
- // We only add path segments to redirect queries if manually
275
- // specified and only automatically add them for rewrites if one
276
- // or more params aren't already used in the destination's path
277
- const paramKeys = Object.keys(indexes);
278
- const needsQueryUpdating =
284
+ }
285
+ const paramKeys = Object.keys(indexes);
286
+ const needsQueryUpdating = (
279
287
  // we do not consider an internal param since it is added automatically
280
- !isRedirect &&
281
- !paramKeys.some(param => !(internalParamNames && internalParamNames.includes(param)) &&
282
- destParams.has(param));
283
- if (needsQueryUpdating) {
284
- for (const param of paramKeys) {
285
- if (!(param in query) && param !== UN_NAMED_SEGMENT) {
286
- query[param] = indexes[param];
287
- }
288
- }
288
+ !isRedirect && !paramKeys.some(
289
+ (param) => !(internalParamNames && internalParamNames.includes(param)) && destParams.has(param)
290
+ )
291
+ );
292
+ if (needsQueryUpdating) {
293
+ for (const param of paramKeys) {
294
+ if (!(param in query) && param !== UN_NAMED_SEGMENT) {
295
+ query[param] = indexes[param];
296
+ }
289
297
  }
290
- destination = (0, url_1.format)({
291
- ...rest,
292
- hostname,
293
- pathname,
294
- query,
295
- hash,
296
- });
297
- // url.format() escapes the dollar sign but it must be preserved for now-proxy
298
- return destination.replace(/%24/g, '$');
298
+ }
299
+ destination = (0, import_url.format)({
300
+ ...rest,
301
+ hostname,
302
+ pathname,
303
+ query,
304
+ hash
305
+ });
306
+ return destination.replace(/%24/g, "$");
299
307
  }
300
308
  function safelyCompile(value, indexes, attemptDirectCompile) {
301
- if (!value) {
302
- return value;
303
- }
304
- if (attemptDirectCompile) {
305
- try {
306
- // Attempt compiling normally with path-to-regexp first and fall back
307
- // to safely compiling to handle edge cases if path-to-regexp compile
308
- // fails
309
- return (0, path_to_regexp_1.compile)(value, { validate: false })(indexes);
310
- }
311
- catch (e) {
312
- // non-fatal, we continue to safely compile
313
- }
309
+ if (!value) {
310
+ return value;
311
+ }
312
+ if (attemptDirectCompile) {
313
+ try {
314
+ return (0, import_path_to_regexp.compile)(value, { validate: false })(indexes);
315
+ } catch (e) {
314
316
  }
315
- for (const key of Object.keys(indexes)) {
316
- if (value.includes(`:${key}`)) {
317
- value = value
318
- .replace(new RegExp(`:${key}\\*`, 'g'), `:${key}--ESCAPED_PARAM_ASTERISK`)
319
- .replace(new RegExp(`:${key}\\?`, 'g'), `:${key}--ESCAPED_PARAM_QUESTION`)
320
- .replace(new RegExp(`:${key}\\+`, 'g'), `:${key}--ESCAPED_PARAM_PLUS`)
321
- .replace(new RegExp(`:${key}(?!\\w)`, 'g'), `--ESCAPED_PARAM_COLON${key}`);
322
- }
317
+ }
318
+ for (const key of Object.keys(indexes)) {
319
+ if (value.includes(`:${key}`)) {
320
+ value = value.replace(
321
+ new RegExp(`:${key}\\*`, "g"),
322
+ `:${key}--ESCAPED_PARAM_ASTERISK`
323
+ ).replace(
324
+ new RegExp(`:${key}\\?`, "g"),
325
+ `:${key}--ESCAPED_PARAM_QUESTION`
326
+ ).replace(new RegExp(`:${key}\\+`, "g"), `:${key}--ESCAPED_PARAM_PLUS`).replace(
327
+ new RegExp(`:${key}(?!\\w)`, "g"),
328
+ `--ESCAPED_PARAM_COLON${key}`
329
+ );
323
330
  }
324
- value = value
325
- .replace(/(:|\*|\?|\+|\(|\)|\{|\})/g, '\\$1')
326
- .replace(/--ESCAPED_PARAM_PLUS/g, '+')
327
- .replace(/--ESCAPED_PARAM_COLON/g, ':')
328
- .replace(/--ESCAPED_PARAM_QUESTION/g, '?')
329
- .replace(/--ESCAPED_PARAM_ASTERISK/g, '*');
330
- // the value needs to start with a forward-slash to be compiled
331
- // correctly
332
- return (0, path_to_regexp_1.compile)(`/${value}`, { validate: false })(indexes).slice(1);
331
+ }
332
+ value = value.replace(/(:|\*|\?|\+|\(|\)|\{|\})/g, "\\$1").replace(/--ESCAPED_PARAM_PLUS/g, "+").replace(/--ESCAPED_PARAM_COLON/g, ":").replace(/--ESCAPED_PARAM_QUESTION/g, "?").replace(/--ESCAPED_PARAM_ASTERISK/g, "*");
333
+ return (0, import_path_to_regexp.compile)(`/${value}`, { validate: false })(indexes).slice(1);
333
334
  }
334
335
  function toSegmentDest(index) {
335
- const i = index + 1; // js is base 0, regex is base 1
336
- return '$' + i.toString();
336
+ const i = index + 1;
337
+ return "$" + i.toString();
337
338
  }
338
339
  function toRoute(filePath) {
339
- return filePath.startsWith('/') ? filePath : '/' + filePath;
340
+ return filePath.startsWith("/") ? filePath : "/" + filePath;
340
341
  }
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ collectHasSegments,
345
+ convertCleanUrls,
346
+ convertHeaders,
347
+ convertRedirects,
348
+ convertRewrites,
349
+ convertTrailingSlash,
350
+ getCleanUrls,
351
+ sourceToRegex
352
+ });