-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathutils.js
More file actions
121 lines (102 loc) · 3.28 KB
/
Copy pathutils.js
File metadata and controls
121 lines (102 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import process from 'node:process';
/**
* Adjusts the stringified route regex for Vercel's routing system
* @param {string} pattern stringified route regex
*/
export function pattern_to_src(pattern) {
let src = pattern
// remove leading / and trailing $/
.slice(1, -2)
// replace escaped \/ with /
.replace(/\\\//g, '/');
// replace the root route "^/" with "^/?"
if (src === '^/') {
src = '^/?';
}
return src;
}
const integer = /^\d+$/;
/**
* @param {false | string | number} value
* @param {string} route_id
* @returns {number | false}
*/
export function parse_isr_expiration(value, route_id) {
if (value === false || value === 'false') return false; // 1 year
/** @param {string} desc */
const err = (desc) => {
throw new Error(
`Invalid isr.expiration value: ${JSON.stringify(value)} (${desc}, in ${route_id})`
);
};
let parsed;
if (typeof value === 'string') {
if (!integer.test(value)) {
err('value was a string but could not be parsed as an integer');
}
parsed = Number.parseInt(value, 10);
} else {
if (!Number.isInteger(value)) {
err('should be an integer');
}
parsed = value;
}
if (Number.isNaN(parsed)) {
err('should be a number');
}
if (parsed < 0) {
err('should be non-negative');
}
return parsed;
}
/**
* @param {string | undefined} default_key
* @param {string | undefined} [override_key]
* @returns {RuntimeKey}
*/
export function resolve_runtime(default_key, override_key) {
const key = override_key ?? default_key ?? get_default_runtime();
assert_is_valid_runtime(key);
return key;
}
const valid_node_versions = [22, 24];
const formatter = new Intl.ListFormat('en-gb', { type: 'disjunction' });
/** @returns {RuntimeKey} */
function get_default_runtime() {
// if the user ran e.g. `bunx --bun vite build`, infer that they want to run the app in Bun
if (process.versions.bun) {
const major = process.versions.bun.split('.')[0];
if (major !== '1') {
throw new Error(
`Unsupported Bun version: ${major}. Please use Bun 1.x to build your project, or explicitly specify a runtime in your adapter configuration.`
);
}
return `bun${major}.x`;
}
// otherwise, default to the version of Node specified in the project config
if (process.versions.node) {
const major = Number(process.versions.node.split('.')[0]);
if (!valid_node_versions.includes(major)) {
throw new Error(
`Unsupported Node.js version: ${process.version}. Please use Node ${formatter.format(valid_node_versions.map((v) => `${v}`))} to build your project, or explicitly specify a runtime in your adapter configuration.`
);
}
return `nodejs${/** @type {22 | 24} */ (major)}.x`;
}
throw new Error(
'Could not auto-detect a runtime. Please explicitly specify a runtime in your adapter configuration.'
);
}
const valid_runtimes = /** @type {const} */ (['nodejs22.x', 'nodejs24.x', 'bun1.x']);
/**
* @param {string} key
* @returns {asserts key is RuntimeKey}
*/
function assert_is_valid_runtime(key) {
if (!valid_runtimes.includes(/** @type {RuntimeKey} */ (key))) {
throw new Error(
`Unsupported runtime: ${key}. Supported runtimes are: ${valid_runtimes.join(', ')}. See the Node.js Version section in your Vercel project settings for info on the currently supported versions.`
);
}
}
/** @typedef {typeof valid_runtimes[number]} RuntimeKey */