@sveltejs/adapter-vercel 1.0.0-next.47 → 1.0.0-next.48
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/README.md +17 -8
- package/files/edge.js +15 -0
- package/files/{entry.js → serverless.js} +3 -1
- package/index.d.ts +2 -0
- package/index.js +294 -87
- package/package.json +2 -2
- package/files/shims.js +0 -2
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ If you're using [adapter-auto](../adapter-auto), you don't need to install this
|
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
|
+
> The `edge` and `split` options depend on the Vercel Build Output API which is currently in beta. For now, you must opt in by visiting `https://vercel.com/svelte/[YOUR_PROJECT]/settings/environment-variables` and adding `ENABLE_VC_BUILD` with the value `1`.
|
|
10
|
+
|
|
9
11
|
Add `"@sveltejs/adapter-vercel": "next"` to the `devDependencies` in your `package.json` and run `npm install`.
|
|
10
12
|
|
|
11
13
|
Then in your `svelte.config.js`:
|
|
@@ -15,18 +17,25 @@ import vercel from '@sveltejs/adapter-vercel';
|
|
|
15
17
|
|
|
16
18
|
export default {
|
|
17
19
|
kit: {
|
|
18
|
-
|
|
19
|
-
adapter: vercel(
|
|
20
|
+
// default options are shown
|
|
21
|
+
adapter: vercel({
|
|
22
|
+
// if true, will deploy the app using edge functions
|
|
23
|
+
// (https://vercel.com/docs/concepts/functions/edge-functions)
|
|
24
|
+
// rather than serverless functions
|
|
25
|
+
edge: false,
|
|
26
|
+
|
|
27
|
+
// an array of dependencies that esbuild should treat
|
|
28
|
+
// as external when bundling functions
|
|
29
|
+
external: [],
|
|
30
|
+
|
|
31
|
+
// if true, will split your app into multiple functions
|
|
32
|
+
// instead of creating a single one for the entire app
|
|
33
|
+
split: false
|
|
34
|
+
})
|
|
20
35
|
}
|
|
21
36
|
};
|
|
22
37
|
```
|
|
23
38
|
|
|
24
|
-
## Options
|
|
25
|
-
|
|
26
|
-
You can pass an `options` argument, if necessary, with the following:
|
|
27
|
-
|
|
28
|
-
- `external` — an array of dependencies that [esbuild](https://esbuild.github.io/api/#external) should treat as external
|
|
29
|
-
|
|
30
39
|
## Changelog
|
|
31
40
|
|
|
32
41
|
[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-vercel/CHANGELOG.md).
|
package/files/edge.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Server } from 'SERVER';
|
|
2
|
+
import { manifest } from 'MANIFEST';
|
|
3
|
+
|
|
4
|
+
const server = new Server(manifest);
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {Request} request
|
|
8
|
+
*/
|
|
9
|
+
export default (request) => {
|
|
10
|
+
return server.respond(request, {
|
|
11
|
+
getClientAddress() {
|
|
12
|
+
return request.headers.get('x-forwarded-for');
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import '
|
|
1
|
+
import { installFetch } from '@sveltejs/kit/install-fetch';
|
|
2
2
|
import { getRequest, setResponse } from '@sveltejs/kit/node';
|
|
3
3
|
import { Server } from 'SERVER';
|
|
4
4
|
import { manifest } from 'MANIFEST';
|
|
5
5
|
|
|
6
|
+
installFetch();
|
|
7
|
+
|
|
6
8
|
const server = new Server(manifest);
|
|
7
9
|
|
|
8
10
|
/**
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { writeFileSync } from 'fs';
|
|
2
|
-
import { posix } from 'path';
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { dirname, posix } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import esbuild from 'esbuild';
|
|
5
5
|
|
|
6
|
-
const dir = '.vercel_build_output';
|
|
7
|
-
|
|
8
6
|
// rules for clean URLs and trailing slash handling,
|
|
9
7
|
// generated with @vercel/routing-utils
|
|
10
8
|
const redirects = {
|
|
@@ -83,99 +81,308 @@ const redirects = {
|
|
|
83
81
|
};
|
|
84
82
|
|
|
85
83
|
/** @type {import('.')} **/
|
|
86
|
-
export default function ({ external = [] } = {}) {
|
|
84
|
+
export default function ({ external = [], edge, split } = {}) {
|
|
87
85
|
return {
|
|
88
86
|
name: '@sveltejs/adapter-vercel',
|
|
89
87
|
|
|
90
88
|
async adapt(builder) {
|
|
91
|
-
|
|
89
|
+
if (process.env.ENABLE_VC_BUILD) {
|
|
90
|
+
await v3(builder, external, edge, split);
|
|
91
|
+
} else {
|
|
92
|
+
if (edge || split) {
|
|
93
|
+
throw new Error('edge and split options can only be used with ENABLE_VC_BUILD');
|
|
94
|
+
}
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
await v1(builder, external);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
95
101
|
|
|
96
|
-
|
|
102
|
+
/**
|
|
103
|
+
* @param {import('@sveltejs/kit').Builder} builder
|
|
104
|
+
* @param {string[]} external
|
|
105
|
+
*/
|
|
106
|
+
async function v1(builder, external) {
|
|
107
|
+
const dir = '.vercel_build_output';
|
|
97
108
|
|
|
98
|
-
|
|
99
|
-
static: `${dir}/static`,
|
|
100
|
-
lambda: `${dir}/functions/node/render`
|
|
101
|
-
};
|
|
109
|
+
const tmp = builder.getBuildDirectory('vercel-tmp');
|
|
102
110
|
|
|
103
|
-
|
|
111
|
+
builder.rimraf(dir);
|
|
112
|
+
builder.rimraf(tmp);
|
|
104
113
|
|
|
105
|
-
|
|
114
|
+
const files = fileURLToPath(new URL('./files', import.meta.url).href);
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
await esbuild.build({
|
|
122
|
-
entryPoints: [`${tmp}/entry.js`],
|
|
123
|
-
outfile: `${dirs.lambda}/index.js`,
|
|
124
|
-
target: 'node14',
|
|
125
|
-
bundle: true,
|
|
126
|
-
platform: 'node',
|
|
127
|
-
external
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
writeFileSync(`${dirs.lambda}/package.json`, JSON.stringify({ type: 'commonjs' }));
|
|
131
|
-
|
|
132
|
-
builder.log.minor('Copying assets...');
|
|
133
|
-
|
|
134
|
-
builder.writeStatic(dirs.static);
|
|
135
|
-
builder.writeClient(dirs.static);
|
|
136
|
-
builder.writePrerendered(dirs.static);
|
|
137
|
-
|
|
138
|
-
builder.log.minor('Writing routes...');
|
|
139
|
-
|
|
140
|
-
builder.mkdirp(`${dir}/config`);
|
|
141
|
-
|
|
142
|
-
const prerendered_pages = Array.from(builder.prerendered.pages, ([src, page]) => ({
|
|
143
|
-
src,
|
|
144
|
-
dest: page.file
|
|
145
|
-
}));
|
|
146
|
-
|
|
147
|
-
const prerendered_redirects = Array.from(
|
|
148
|
-
builder.prerendered.redirects,
|
|
149
|
-
([src, redirect]) => ({
|
|
150
|
-
src,
|
|
151
|
-
headers: {
|
|
152
|
-
Location: redirect.location
|
|
153
|
-
},
|
|
154
|
-
status: redirect.status
|
|
155
|
-
})
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
writeFileSync(
|
|
159
|
-
`${dir}/config/routes.json`,
|
|
160
|
-
JSON.stringify([
|
|
161
|
-
...redirects[builder.config.kit.trailingSlash],
|
|
162
|
-
...prerendered_pages,
|
|
163
|
-
...prerendered_redirects,
|
|
164
|
-
{
|
|
165
|
-
src: `/${builder.config.kit.appDir}/.+`,
|
|
166
|
-
headers: {
|
|
167
|
-
'cache-control': 'public, immutable, max-age=31536000'
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
handle: 'filesystem'
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
src: '/.*',
|
|
175
|
-
dest: '.vercel/functions/render'
|
|
176
|
-
}
|
|
177
|
-
])
|
|
178
|
-
);
|
|
116
|
+
const dirs = {
|
|
117
|
+
static: `${dir}/static`,
|
|
118
|
+
lambda: `${dir}/functions/node/render`
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
builder.log.minor('Generating serverless function...');
|
|
122
|
+
|
|
123
|
+
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
124
|
+
|
|
125
|
+
builder.copy(`${files}/serverless.js`, `${tmp}/serverless.js`, {
|
|
126
|
+
replace: {
|
|
127
|
+
SERVER: `${relativePath}/index.js`,
|
|
128
|
+
MANIFEST: './manifest.js'
|
|
179
129
|
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
writeFileSync(
|
|
133
|
+
`${tmp}/manifest.js`,
|
|
134
|
+
`export const manifest = ${builder.generateManifest({
|
|
135
|
+
relativePath
|
|
136
|
+
})};\n`
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
await esbuild.build({
|
|
140
|
+
entryPoints: [`${tmp}/serverless.js`],
|
|
141
|
+
outfile: `${dirs.lambda}/index.js`,
|
|
142
|
+
target: 'node14',
|
|
143
|
+
bundle: true,
|
|
144
|
+
platform: 'node',
|
|
145
|
+
external
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
writeFileSync(`${dirs.lambda}/package.json`, JSON.stringify({ type: 'commonjs' }));
|
|
149
|
+
|
|
150
|
+
builder.log.minor('Copying assets...');
|
|
151
|
+
|
|
152
|
+
builder.writeStatic(dirs.static);
|
|
153
|
+
builder.writeClient(dirs.static);
|
|
154
|
+
builder.writePrerendered(dirs.static);
|
|
155
|
+
|
|
156
|
+
builder.log.minor('Writing routes...');
|
|
157
|
+
|
|
158
|
+
builder.mkdirp(`${dir}/config`);
|
|
159
|
+
|
|
160
|
+
const prerendered_pages = Array.from(builder.prerendered.pages, ([src, page]) => ({
|
|
161
|
+
src,
|
|
162
|
+
dest: page.file
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
const prerendered_redirects = Array.from(builder.prerendered.redirects, ([src, redirect]) => ({
|
|
166
|
+
src,
|
|
167
|
+
headers: {
|
|
168
|
+
Location: redirect.location
|
|
169
|
+
},
|
|
170
|
+
status: redirect.status
|
|
171
|
+
}));
|
|
172
|
+
|
|
173
|
+
writeFileSync(
|
|
174
|
+
`${dir}/config/routes.json`,
|
|
175
|
+
JSON.stringify([
|
|
176
|
+
...redirects[builder.config.kit.trailingSlash],
|
|
177
|
+
...prerendered_pages,
|
|
178
|
+
...prerendered_redirects,
|
|
179
|
+
{
|
|
180
|
+
src: `/${builder.config.kit.appDir}/.+`,
|
|
181
|
+
headers: {
|
|
182
|
+
'cache-control': 'public, immutable, max-age=31536000'
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
handle: 'filesystem'
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
src: '/.*',
|
|
190
|
+
dest: '.vercel/functions/render'
|
|
191
|
+
}
|
|
192
|
+
])
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @param {import('@sveltejs/kit').Builder} builder
|
|
198
|
+
* @param {string[]} external
|
|
199
|
+
* @param {boolean} edge
|
|
200
|
+
* @param {boolean} split
|
|
201
|
+
*/
|
|
202
|
+
async function v3(builder, external, edge, split) {
|
|
203
|
+
const dir = '.vercel/output';
|
|
204
|
+
|
|
205
|
+
const tmp = builder.getBuildDirectory('vercel-tmp');
|
|
206
|
+
|
|
207
|
+
builder.rimraf(dir);
|
|
208
|
+
builder.rimraf(tmp);
|
|
209
|
+
|
|
210
|
+
const files = fileURLToPath(new URL('./files', import.meta.url).href);
|
|
211
|
+
|
|
212
|
+
const dirs = {
|
|
213
|
+
static: `${dir}/static`,
|
|
214
|
+
functions: `${dir}/functions`
|
|
180
215
|
};
|
|
216
|
+
|
|
217
|
+
const prerendered_redirects = Array.from(builder.prerendered.redirects, ([src, redirect]) => ({
|
|
218
|
+
src,
|
|
219
|
+
headers: {
|
|
220
|
+
Location: redirect.location
|
|
221
|
+
},
|
|
222
|
+
status: redirect.status
|
|
223
|
+
}));
|
|
224
|
+
|
|
225
|
+
/** @type {any[]} */
|
|
226
|
+
const routes = [
|
|
227
|
+
...redirects[builder.config.kit.trailingSlash],
|
|
228
|
+
...prerendered_redirects,
|
|
229
|
+
{
|
|
230
|
+
src: `/${builder.config.kit.appDir}/.+`,
|
|
231
|
+
headers: {
|
|
232
|
+
'cache-control': 'public, immutable, max-age=31536000'
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
handle: 'filesystem'
|
|
237
|
+
}
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
builder.log.minor('Generating serverless function...');
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @param {string} name
|
|
244
|
+
* @param {string} pattern
|
|
245
|
+
* @param {(options: { relativePath: string }) => string} generate_manifest
|
|
246
|
+
*/
|
|
247
|
+
async function generate_serverless_function(name, pattern, generate_manifest) {
|
|
248
|
+
const tmp = builder.getBuildDirectory(`vercel-tmp/${name}`);
|
|
249
|
+
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
250
|
+
|
|
251
|
+
builder.copy(`${files}/serverless.js`, `${tmp}/serverless.js`, {
|
|
252
|
+
replace: {
|
|
253
|
+
SERVER: `${relativePath}/index.js`,
|
|
254
|
+
MANIFEST: './manifest.js'
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
write(
|
|
259
|
+
`${tmp}/manifest.js`,
|
|
260
|
+
`export const manifest = ${generate_manifest({ relativePath })};\n`
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
await esbuild.build({
|
|
264
|
+
entryPoints: [`${tmp}/serverless.js`],
|
|
265
|
+
outfile: `${dirs.functions}/${name}.func/index.js`,
|
|
266
|
+
target: 'node14',
|
|
267
|
+
bundle: true,
|
|
268
|
+
platform: 'node',
|
|
269
|
+
format: 'cjs',
|
|
270
|
+
external
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
write(
|
|
274
|
+
`${dirs.functions}/${name}.func/.vc-config.json`,
|
|
275
|
+
JSON.stringify({
|
|
276
|
+
runtime: 'nodejs14.x',
|
|
277
|
+
handler: 'index.js',
|
|
278
|
+
launcherType: 'Nodejs'
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
write(`${dirs.functions}/${name}.func/package.json`, JSON.stringify({ type: 'commonjs' }));
|
|
283
|
+
|
|
284
|
+
routes.push({ src: pattern, dest: `/${name}` });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @param {string} name
|
|
289
|
+
* @param {string} pattern
|
|
290
|
+
* @param {(options: { relativePath: string }) => string} generate_manifest
|
|
291
|
+
*/
|
|
292
|
+
async function generate_edge_function(name, pattern, generate_manifest) {
|
|
293
|
+
const tmp = builder.getBuildDirectory(`vercel-tmp/${name}`);
|
|
294
|
+
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
295
|
+
|
|
296
|
+
builder.copy(`${files}/edge.js`, `${tmp}/edge.js`, {
|
|
297
|
+
replace: {
|
|
298
|
+
SERVER: `${relativePath}/index.js`,
|
|
299
|
+
MANIFEST: './manifest.js'
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
write(
|
|
304
|
+
`${tmp}/manifest.js`,
|
|
305
|
+
`export const manifest = ${generate_manifest({ relativePath })};\n`
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
await esbuild.build({
|
|
309
|
+
entryPoints: [`${tmp}/edge.js`],
|
|
310
|
+
outfile: `${dirs.functions}/${name}.func/index.js`,
|
|
311
|
+
target: 'node14',
|
|
312
|
+
bundle: true,
|
|
313
|
+
platform: 'node',
|
|
314
|
+
format: 'esm',
|
|
315
|
+
external
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
write(
|
|
319
|
+
`${dirs.functions}/${name}.func/.vc-config.json`,
|
|
320
|
+
JSON.stringify({
|
|
321
|
+
runtime: 'edge',
|
|
322
|
+
entrypoint: 'index.js'
|
|
323
|
+
// TODO expose envVarsInUse
|
|
324
|
+
})
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
routes.push({ src: pattern, middlewarePath: name });
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const generate_function = edge ? generate_edge_function : generate_serverless_function;
|
|
331
|
+
|
|
332
|
+
if (split) {
|
|
333
|
+
await builder.createEntries((route) => {
|
|
334
|
+
return {
|
|
335
|
+
id: route.pattern.toString(), // TODO is `id` necessary?
|
|
336
|
+
filter: (other) => route.pattern.toString() === other.pattern.toString(),
|
|
337
|
+
complete: async (entry) => {
|
|
338
|
+
const src = `${route.pattern
|
|
339
|
+
.toString()
|
|
340
|
+
.slice(1, -2) // remove leading / and trailing $/
|
|
341
|
+
.replace(/\\\//g, '/')}(?:/__data.json)?$`; // TODO adding /__data.json is a temporary workaround — those endpoints should be treated as distinct routes
|
|
342
|
+
|
|
343
|
+
await generate_function(route.id, src, entry.generateManifest);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
});
|
|
347
|
+
} else {
|
|
348
|
+
await generate_function('render', '/.*', builder.generateManifest);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
builder.log.minor('Copying assets...');
|
|
352
|
+
|
|
353
|
+
builder.writeStatic(dirs.static);
|
|
354
|
+
builder.writeClient(dirs.static);
|
|
355
|
+
builder.writePrerendered(dirs.static);
|
|
356
|
+
|
|
357
|
+
builder.log.minor('Writing routes...');
|
|
358
|
+
|
|
359
|
+
/** @type {Record<string, { path: string }>} */
|
|
360
|
+
const overrides = {};
|
|
361
|
+
builder.prerendered.pages.forEach((page, src) => {
|
|
362
|
+
overrides[page.file] = { path: src.slice(1) };
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
write(
|
|
366
|
+
`${dir}/config.json`,
|
|
367
|
+
JSON.stringify({
|
|
368
|
+
version: 3,
|
|
369
|
+
target: 'production',
|
|
370
|
+
routes,
|
|
371
|
+
overrides
|
|
372
|
+
})
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @param {string} file
|
|
378
|
+
* @param {string} data
|
|
379
|
+
*/
|
|
380
|
+
function write(file, data) {
|
|
381
|
+
try {
|
|
382
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
383
|
+
} catch {
|
|
384
|
+
// do nothing
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
writeFileSync(file, data);
|
|
181
388
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/adapter-vercel",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.48",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sveltejs/kit",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"esbuild": "^0.14.21"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@sveltejs/kit": "1.0.0-next.
|
|
28
|
+
"@sveltejs/kit": "1.0.0-next.317",
|
|
29
29
|
"typescript": "^4.6.2"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
package/files/shims.js
DELETED