@sveltejs/adapter-vercel 5.0.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +59 -26
- package/package.json +2 -2
- package/utils.js +58 -12
package/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { nodeFileTrace } from '@vercel/nft';
|
|
5
5
|
import esbuild from 'esbuild';
|
|
6
|
-
import { get_pathname } from './utils.js';
|
|
6
|
+
import { get_pathname, pattern_to_src } from './utils.js';
|
|
7
7
|
|
|
8
8
|
const name = '@sveltejs/adapter-vercel';
|
|
9
9
|
const DEFAULT_FUNCTION_NAME = 'fn';
|
|
@@ -18,6 +18,9 @@ const get_default_runtime = () => {
|
|
|
18
18
|
);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
// https://vercel.com/docs/functions/edge-functions/edge-runtime#compatible-node.js-modules
|
|
22
|
+
const compatible_node_modules = ['async_hooks', 'events', 'buffer', 'assert', 'util'];
|
|
23
|
+
|
|
21
24
|
/** @type {import('.').default} **/
|
|
22
25
|
const plugin = function (defaults = {}) {
|
|
23
26
|
if ('edge' in defaults) {
|
|
@@ -109,20 +112,61 @@ const plugin = function (defaults = {}) {
|
|
|
109
112
|
`export const manifest = ${builder.generateManifest({ relativePath, routes })};\n`
|
|
110
113
|
);
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
try {
|
|
116
|
+
const result = await esbuild.build({
|
|
117
|
+
entryPoints: [`${tmp}/edge.js`],
|
|
118
|
+
outfile: `${dirs.functions}/${name}.func/index.js`,
|
|
119
|
+
target: 'es2020', // TODO verify what the edge runtime supports
|
|
120
|
+
bundle: true,
|
|
121
|
+
platform: 'browser',
|
|
122
|
+
format: 'esm',
|
|
123
|
+
external: [
|
|
124
|
+
...compatible_node_modules,
|
|
125
|
+
...compatible_node_modules.map((id) => `node:${id}`),
|
|
126
|
+
...(config.external || [])
|
|
127
|
+
],
|
|
128
|
+
sourcemap: 'linked',
|
|
129
|
+
banner: { js: 'globalThis.global = globalThis;' },
|
|
130
|
+
loader: {
|
|
131
|
+
'.wasm': 'copy'
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (result.warnings.length > 0) {
|
|
136
|
+
const formatted = await esbuild.formatMessages(result.warnings, {
|
|
137
|
+
kind: 'warning',
|
|
138
|
+
color: true
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.error(formatted.join('\n'));
|
|
124
142
|
}
|
|
125
|
-
})
|
|
143
|
+
} catch (error) {
|
|
144
|
+
for (const e of error.errors) {
|
|
145
|
+
for (const node of e.notes) {
|
|
146
|
+
const match =
|
|
147
|
+
/The package "(.+)" wasn't found on the file system but is built into node/.exec(
|
|
148
|
+
node.text
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (match) {
|
|
152
|
+
node.text = `Cannot use "${match[1]}" when deploying to Vercel Edge Functions.`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const formatted = await esbuild.formatMessages(error.errors, {
|
|
158
|
+
kind: 'error',
|
|
159
|
+
color: true
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
console.error(formatted.join('\n'));
|
|
163
|
+
|
|
164
|
+
throw new Error(
|
|
165
|
+
`Bundling with esbuild failed with ${error.errors.length} ${
|
|
166
|
+
error.errors.length === 1 ? 'error' : 'errors'
|
|
167
|
+
}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
126
170
|
|
|
127
171
|
write(
|
|
128
172
|
`${dirs.functions}/${name}.func/.vc-config.json`,
|
|
@@ -261,18 +305,7 @@ const plugin = function (defaults = {}) {
|
|
|
261
305
|
if (is_prerendered(route)) continue;
|
|
262
306
|
|
|
263
307
|
const pattern = route.pattern.toString();
|
|
264
|
-
|
|
265
|
-
let src = pattern
|
|
266
|
-
// remove leading / and trailing $/
|
|
267
|
-
.slice(1, -2)
|
|
268
|
-
// replace escaped \/ with /
|
|
269
|
-
.replace(/\\\//g, '/');
|
|
270
|
-
|
|
271
|
-
// replace the root route "^/" with "^/?"
|
|
272
|
-
if (src === '^/') {
|
|
273
|
-
src = '^/?';
|
|
274
|
-
}
|
|
275
|
-
|
|
308
|
+
const src = pattern_to_src(pattern);
|
|
276
309
|
const name = functions.get(pattern) ?? 'fn-0';
|
|
277
310
|
|
|
278
311
|
const isr = isr_config.get(route);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/adapter-vercel",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "A SvelteKit adapter that creates a Vercel app",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/node": "^18.19.3",
|
|
34
34
|
"typescript": "^5.3.3",
|
|
35
35
|
"vitest": "^1.2.0",
|
|
36
|
-
"@sveltejs/kit": "^2.
|
|
36
|
+
"@sveltejs/kit": "^2.5.3"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@sveltejs/kit": "^2.4.0"
|
package/utils.js
CHANGED
|
@@ -2,22 +2,68 @@
|
|
|
2
2
|
export function get_pathname(route) {
|
|
3
3
|
let i = 1;
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const pathname = route.segments
|
|
6
6
|
.map((segment) => {
|
|
7
7
|
if (!segment.dynamic) {
|
|
8
|
-
return segment.content;
|
|
8
|
+
return '/' + segment.content;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
const parts = segment.content.split(/\[(.+?)\](?!\])/);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.
|
|
12
|
+
let result = '';
|
|
13
|
+
|
|
14
|
+
if (
|
|
15
|
+
parts.length === 3 &&
|
|
16
|
+
!parts[0] &&
|
|
17
|
+
!parts[2] &&
|
|
18
|
+
(parts[1].startsWith('...') || parts[1][0] === '[')
|
|
19
|
+
) {
|
|
20
|
+
// Special case: segment is a single optional or rest parameter.
|
|
21
|
+
// In that case we don't prepend a slash (also see comment in pattern_to_src).
|
|
22
|
+
result = `$${i++}`;
|
|
23
|
+
} else {
|
|
24
|
+
result =
|
|
25
|
+
'/' +
|
|
26
|
+
parts
|
|
27
|
+
.map((content, j) => {
|
|
28
|
+
if (j % 2) {
|
|
29
|
+
return `$${i++}`;
|
|
30
|
+
} else {
|
|
31
|
+
return content;
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.join('');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return result;
|
|
21
38
|
})
|
|
22
|
-
.join('
|
|
39
|
+
.join('');
|
|
40
|
+
|
|
41
|
+
return pathname[0] === '/' ? pathname.slice(1) : pathname;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Adjusts the stringified route regex for Vercel's routing system
|
|
46
|
+
* @param {string} pattern stringified route regex
|
|
47
|
+
*/
|
|
48
|
+
export function pattern_to_src(pattern) {
|
|
49
|
+
let src = pattern
|
|
50
|
+
// remove leading / and trailing $/
|
|
51
|
+
.slice(1, -2)
|
|
52
|
+
// replace escaped \/ with /
|
|
53
|
+
.replace(/\\\//g, '/');
|
|
54
|
+
|
|
55
|
+
// replace the root route "^/" with "^/?"
|
|
56
|
+
if (src === '^/') {
|
|
57
|
+
src = '^/?';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Move non-capturing groups that swallow slashes into their following capturing groups.
|
|
61
|
+
// This is necessary because during ISR we're using the regex to construct the __pathname
|
|
62
|
+
// query parameter: In case of a route like [required]/[...rest] we need to turn them
|
|
63
|
+
// into $1$2 and not $1/$2, because if [...rest] is empty, we don't want to have a trailing
|
|
64
|
+
// slash in the __pathname query parameter which wasn't there in the original URL, as that
|
|
65
|
+
// could result in a false trailing slash redirect in the SvelteKit runtime, leading to infinite redirects.
|
|
66
|
+
src = src.replace(/\(\?:\/\((.+?)\)\)/g, '(/$1)');
|
|
67
|
+
|
|
68
|
+
return src;
|
|
23
69
|
}
|