@sst-community/svelte-kit-sst 3.0.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,587 @@
1
+ # svelte-kit-sst
2
+
3
+ ## 3.0.0
4
+
5
+ The first release as `@sst-community/svelte-kit-sst`, from the sst-community fork.
6
+
7
+ - Works with SvelteKit 3 as well as 2. On SvelteKit 3 the server is built with `builder.generateServerInstance`; SvelteKit 2 behaves as before, Node polyfills included.
8
+ - A route that uses `read` from `$app/server` fails the build with a clear message, since client assets are served from S3 and aren't in the function.
9
+ - Install it as `svelte-kit-sst@npm:@sst-community/svelte-kit-sst`, so `import adapter from "svelte-kit-sst"` keeps working.
10
+
11
+ ## 2.44.0
12
+
13
+ ## 2.43.8
14
+
15
+ ## 2.43.7
16
+
17
+ ## 2.43.6
18
+
19
+ ### Patch Changes
20
+
21
+ - [`a68ca8416`](https://github.com/sst/sst/commit/a68ca84160bc87460e4fb09a4893640ad11daebf) Thanks [@thdxr](https://github.com/thdxr)! - switch to v2 tag
22
+
23
+ ## 2.43.5
24
+
25
+ ## 2.43.4
26
+
27
+ ## 2.43.3
28
+
29
+ ## 2.43.2
30
+
31
+ ## 2.43.1
32
+
33
+ ## 2.43.0
34
+
35
+ ## 2.42.0
36
+
37
+ ## 2.41.5
38
+
39
+ ## 2.41.4
40
+
41
+ ## 2.41.3
42
+
43
+ ## 2.41.2
44
+
45
+ ## 2.41.1
46
+
47
+ ## 2.41.0
48
+
49
+ ## 2.40.8
50
+
51
+ ## 2.40.7
52
+
53
+ ## 2.40.6
54
+
55
+ ## 2.40.5
56
+
57
+ ## 2.40.4
58
+
59
+ ## 2.40.3
60
+
61
+ ## 2.40.2
62
+
63
+ ## 2.40.1
64
+
65
+ ## 2.40.0
66
+
67
+ ## 2.39.13
68
+
69
+ ## 2.39.12
70
+
71
+ ## 2.39.11
72
+
73
+ ## 2.39.10
74
+
75
+ ## 2.39.9
76
+
77
+ ## 2.39.8
78
+
79
+ ## 2.39.7
80
+
81
+ ## 2.39.6
82
+
83
+ ## 2.39.5
84
+
85
+ ## 2.39.4
86
+
87
+ ## 2.39.3
88
+
89
+ ## 2.39.2
90
+
91
+ ## 2.39.1
92
+
93
+ ## 2.39.0
94
+
95
+ ## 2.38.7
96
+
97
+ ## 2.38.6
98
+
99
+ ## 2.38.5
100
+
101
+ ## 2.38.4
102
+
103
+ ## 2.38.3
104
+
105
+ ## 2.38.2
106
+
107
+ ## 2.38.1
108
+
109
+ ## 2.38.0
110
+
111
+ ## 2.37.2
112
+
113
+ ## 2.37.1
114
+
115
+ ## 2.37.0
116
+
117
+ ## 2.36.8
118
+
119
+ ## 2.36.7
120
+
121
+ ## 2.36.6
122
+
123
+ ## 2.36.5
124
+
125
+ ## 2.36.4
126
+
127
+ ## 2.36.3
128
+
129
+ ## 2.36.2
130
+
131
+ ## 2.36.1
132
+
133
+ ## 2.36.0
134
+
135
+ ## 2.35.1
136
+
137
+ ## 2.35.0
138
+
139
+ ## 2.34.7
140
+
141
+ ## 2.34.6
142
+
143
+ ## 2.34.5
144
+
145
+ ## 2.34.4
146
+
147
+ ## 2.34.3
148
+
149
+ ## 2.34.2
150
+
151
+ ## 2.34.1
152
+
153
+ ## 2.34.0
154
+
155
+ ## 2.33.4
156
+
157
+ ## 2.33.3
158
+
159
+ ## 2.33.2
160
+
161
+ ## 2.33.1
162
+
163
+ ## 2.33.0
164
+
165
+ ## 2.32.3
166
+
167
+ ## 2.32.2
168
+
169
+ ## 2.32.1
170
+
171
+ ## 2.32.0
172
+
173
+ ## 2.31.0
174
+
175
+ ## 2.30.4
176
+
177
+ ## 2.30.3
178
+
179
+ ## 2.30.2
180
+
181
+ ## 2.30.1
182
+
183
+ ## 2.30.0
184
+
185
+ ## 2.29.2
186
+
187
+ ## 2.29.1
188
+
189
+ ## 2.29.0
190
+
191
+ ## 2.28.6
192
+
193
+ ## 2.28.5
194
+
195
+ ## 2.28.4
196
+
197
+ ## 2.28.3
198
+
199
+ ## 2.28.2
200
+
201
+ ## 2.28.1
202
+
203
+ ## 2.28.0
204
+
205
+ ## 2.27.0
206
+
207
+ ## 2.26.11
208
+
209
+ ## 2.26.10
210
+
211
+ ## 2.26.9
212
+
213
+ ## 2.26.8
214
+
215
+ ## 2.26.7
216
+
217
+ ## 2.26.6
218
+
219
+ ## 2.26.5
220
+
221
+ ## 2.26.4
222
+
223
+ ## 2.26.3
224
+
225
+ ## 2.26.2
226
+
227
+ ## 2.26.1
228
+
229
+ ## 2.26.0
230
+
231
+ ## 2.25.7
232
+
233
+ ## 2.25.6
234
+
235
+ ## 2.25.5
236
+
237
+ ## 2.25.4
238
+
239
+ ## 2.25.3
240
+
241
+ ## 2.25.2
242
+
243
+ ## 2.25.1
244
+
245
+ ## 2.25.0
246
+
247
+ ## 2.24.28
248
+
249
+ ## 2.24.27
250
+
251
+ ## 2.24.26
252
+
253
+ ## 2.24.25
254
+
255
+ ## 2.24.24
256
+
257
+ ## 2.24.23
258
+
259
+ ## 2.24.22
260
+
261
+ ## 2.24.21
262
+
263
+ ## 2.24.20
264
+
265
+ ## 2.24.19
266
+
267
+ ## 2.24.18
268
+
269
+ ## 2.24.17
270
+
271
+ ## 2.24.16
272
+
273
+ ## 2.24.15
274
+
275
+ ## 2.24.14
276
+
277
+ ## 2.24.13
278
+
279
+ ## 2.24.12
280
+
281
+ ## 2.24.11
282
+
283
+ ## 2.24.10
284
+
285
+ ## 2.24.9
286
+
287
+ ## 2.24.8
288
+
289
+ ## 2.24.7
290
+
291
+ ## 2.24.6
292
+
293
+ ## 2.24.5
294
+
295
+ ## 2.24.4
296
+
297
+ ## 2.24.3
298
+
299
+ ## 2.24.2
300
+
301
+ ## 2.24.1
302
+
303
+ ## 2.24.0
304
+
305
+ ### Patch Changes
306
+
307
+ - [#3201](https://github.com/sst/sst/pull/3201) [`f5a7d5609`](https://github.com/sst/sst/commit/f5a7d560930434b48d1970c7eddf3c5044caae58) Thanks [@jayair](https://github.com/jayair)! - Update serverless-stack to sst
308
+
309
+ ## 2.23.15
310
+
311
+ ## 2.23.14
312
+
313
+ ## 2.23.13
314
+
315
+ ## 2.23.12
316
+
317
+ ## 2.23.11
318
+
319
+ ## 2.23.10
320
+
321
+ ## 2.23.9
322
+
323
+ ## 2.23.8
324
+
325
+ ## 2.23.7
326
+
327
+ ## 2.23.6
328
+
329
+ ## 2.23.5
330
+
331
+ ## 2.23.4
332
+
333
+ ## 2.23.3
334
+
335
+ ## 2.23.2
336
+
337
+ ## 2.23.1
338
+
339
+ ## 2.23.0
340
+
341
+ ## 2.22.11
342
+
343
+ ## 2.22.10
344
+
345
+ ## 2.22.9
346
+
347
+ ## 2.22.8
348
+
349
+ ## 2.22.7
350
+
351
+ ## 2.22.6
352
+
353
+ ## 2.22.5
354
+
355
+ ## 2.22.4
356
+
357
+ ## 2.22.3
358
+
359
+ ## 2.22.2
360
+
361
+ ## 2.22.1
362
+
363
+ ## 2.22.0
364
+
365
+ ## 2.21.8
366
+
367
+ ## 2.21.7
368
+
369
+ ## 2.21.6
370
+
371
+ ## 2.21.5
372
+
373
+ ## 2.21.4
374
+
375
+ ## 2.21.3
376
+
377
+ ## 2.21.2
378
+
379
+ ## 2.21.1
380
+
381
+ ## 2.21.0
382
+
383
+ ## 2.20.1
384
+
385
+ ## 2.20.0
386
+
387
+ ## 2.19.2
388
+
389
+ ## 2.19.1
390
+
391
+ ## 2.19.0
392
+
393
+ ## 2.18.4
394
+
395
+ ## 2.18.3
396
+
397
+ ## 2.18.2
398
+
399
+ ## 2.18.1
400
+
401
+ ## 2.18.0
402
+
403
+ ## 2.17.8
404
+
405
+ ## 2.17.7
406
+
407
+ ## 2.17.6
408
+
409
+ ## 2.17.5
410
+
411
+ ## 2.17.4
412
+
413
+ ## 2.17.3
414
+
415
+ ## 2.17.2
416
+
417
+ ## 2.17.1
418
+
419
+ ## 2.17.0
420
+
421
+ ## 2.16.4
422
+
423
+ ## 2.16.3
424
+
425
+ ## 2.16.2
426
+
427
+ ## 2.16.1
428
+
429
+ ## 2.16.0
430
+
431
+ ## 2.15.0
432
+
433
+ ## 2.14.0
434
+
435
+ ## 2.13.9
436
+
437
+ ## 2.13.8
438
+
439
+ ## 2.13.7
440
+
441
+ ## 2.13.6
442
+
443
+ ## 2.13.5
444
+
445
+ ## 2.13.4
446
+
447
+ ## 2.13.3
448
+
449
+ ## 2.13.2
450
+
451
+ ## 2.13.1
452
+
453
+ ## 2.13.0
454
+
455
+ ## 2.12.2
456
+
457
+ ## 2.12.1
458
+
459
+ ## 2.12.0
460
+
461
+ ## 2.11.18
462
+
463
+ ## 2.11.17
464
+
465
+ ## 2.11.16
466
+
467
+ ## 2.11.15
468
+
469
+ ## 2.11.14
470
+
471
+ ## 2.11.13
472
+
473
+ ## 2.11.12
474
+
475
+ ## 2.11.11
476
+
477
+ ## 2.11.10
478
+
479
+ ## 2.11.9
480
+
481
+ ## 2.11.8
482
+
483
+ ## 2.11.7
484
+
485
+ ## 2.11.6
486
+
487
+ ## 2.11.5
488
+
489
+ ## 2.11.4
490
+
491
+ ## 2.11.3
492
+
493
+ ## 2.11.2
494
+
495
+ ## 2.11.1
496
+
497
+ ## 2.11.0
498
+
499
+ ## 2.10.4
500
+
501
+ ## 2.10.3
502
+
503
+ ## 2.10.2
504
+
505
+ ## 2.10.1
506
+
507
+ ## 2.10.0
508
+
509
+ ## 2.9.0
510
+
511
+ ## 2.8.29
512
+
513
+ ## 2.8.28
514
+
515
+ ## 2.8.27
516
+
517
+ ## 2.8.26
518
+
519
+ ## 2.8.25
520
+
521
+ ## 2.8.24
522
+
523
+ ## 2.8.23
524
+
525
+ ## 2.8.22
526
+
527
+ ## 2.8.21
528
+
529
+ ## 2.8.20
530
+
531
+ ## 2.8.19
532
+
533
+ ## 2.8.18
534
+
535
+ ### Patch Changes
536
+
537
+ - [`04f01b75b`](https://github.com/serverless-stack/sst/commit/04f01b75b72dc7310911ac5da8554ebdbf5699f4) Thanks [@fwang](https://github.com/fwang)! - SvelteKitSite: fix response cookies not set
538
+
539
+ ## 2.8.17
540
+
541
+ ## 2.8.16
542
+
543
+ ## 2.8.15
544
+
545
+ ## 2.8.14
546
+
547
+ ## 2.8.13
548
+
549
+ ## 2.8.12
550
+
551
+ ### Patch Changes
552
+
553
+ - [`c3e5acdc3`](https://github.com/serverless-stack/sst/commit/c3e5acdc3758a1f8b008206323b8dbb45ea704d0) Thanks [@fwang](https://github.com/fwang)! - SvelteKitSite: update adapter output destination
554
+
555
+ ## 2.8.11
556
+
557
+ ## 2.8.10
558
+
559
+ ## 2.8.9
560
+
561
+ ## 2.8.8
562
+
563
+ ## 2.8.7
564
+
565
+ ## 2.8.6
566
+
567
+ ## 2.8.5
568
+
569
+ ## 2.8.4
570
+
571
+ ## 2.8.3
572
+
573
+ ## 2.8.2
574
+
575
+ ## 2.8.1
576
+
577
+ ### Patch Changes
578
+
579
+ - [`6cd6c2d1e`](https://github.com/serverless-stack/sst/commit/6cd6c2d1eae10979fabdfad6912e61a3c7211e3f) Thanks [@fwang](https://github.com/fwang)! - Add support for SvelteKit
580
+
581
+ ## 2.8.0
582
+
583
+ ### Minor Changes
584
+
585
+ - [#2824](https://github.com/serverless-stack/sst/pull/2824) [`eebce13c1`](https://github.com/serverless-stack/sst/commit/eebce13c18cb51f2fd6ead53492ed5d8fc375040) Thanks [@fwang](https://github.com/fwang)! - Add support for SvelteKit
586
+
587
+ ## 2.7.2
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 SST
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # svelte-kit-sst
2
+
3
+ This adapter allows SvelteKit to deploy your SSR site to [AWS](https://aws.amazon.com/). It's the sst-community build of SST's `svelte-kit-sst`, published as `@sst-community/svelte-kit-sst`.
4
+
5
+ ## Installation
6
+
7
+ Install it under the name `svelte-kit-sst`, so `import adapter from "svelte-kit-sst"` keeps working.
8
+
9
+ ```bash
10
+ npm install svelte-kit-sst@npm:@sst-community/svelte-kit-sst
11
+ # pnpm add svelte-kit-sst@npm:@sst-community/svelte-kit-sst
12
+ # bun add svelte-kit-sst@npm:@sst-community/svelte-kit-sst
13
+ # yarn add svelte-kit-sst@npm:@sst-community/svelte-kit-sst
14
+ ```
15
+
16
+ To switch an existing project, change its dependency to `"svelte-kit-sst": "npm:@sst-community/svelte-kit-sst@<version>"` and reinstall.
17
+
18
+ One package works with SvelteKit 2 and 3. It's tested with 2.70 and 3.0.
19
+
20
+ ### SvelteKit 3
21
+
22
+ SvelteKit 3 keeps its configuration in `vite.config.ts`. Add the adapter to the `sveltekit()` plugin.
23
+
24
+ ```diff
25
+ + import adapter from "svelte-kit-sst";
26
+ import { sveltekit } from "@sveltejs/kit/vite";
27
+ import { defineConfig } from "vite";
28
+
29
+ export default defineConfig({
30
+ plugins: [
31
+ sveltekit({
32
+ + adapter: adapter(),
33
+ }),
34
+ ],
35
+ });
36
+ ```
37
+
38
+ SvelteKit 3 itself requires Node 22.17 or newer.
39
+
40
+ ### SvelteKit 2
41
+
42
+ SvelteKit 2 reads the adapter from `svelte.config.js`. The install and the import are the same.
43
+
44
+ ```diff
45
+ + import adapter from "svelte-kit-sst";
46
+ import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
47
+
48
+ const config = {
49
+ preprocess: vitePreprocess(),
50
+ kit: {
51
+ + adapter: adapter(),
52
+ },
53
+ };
54
+
55
+ export default config;
56
+ ```
57
+
58
+ ## Limitations
59
+
60
+ - `read` from `$app/server` isn't supported. The function only contains the server code and prerendered pages, and client assets are served from S3. A route that uses `read` fails the build with an error that says so.
61
+ - Server instrumentation (`instrumentation.server.js`) isn't supported yet.
@@ -0,0 +1 @@
1
+ export declare function isBinaryContentType(contentType?: string | null): boolean;
@@ -0,0 +1,63 @@
1
+ const commonBinaryMimeTypes = new Set([
2
+ "application/octet-stream",
3
+ // Docs
4
+ "application/epub+zip",
5
+ "application/msword",
6
+ "application/pdf",
7
+ "application/rtf",
8
+ "application/vnd.amazon.ebook",
9
+ "application/vnd.ms-excel",
10
+ "application/vnd.ms-powerpoint",
11
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
12
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
13
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
14
+ // Fonts
15
+ "font/otf",
16
+ "font/woff",
17
+ "font/woff2",
18
+ // Images
19
+ "image/bmp",
20
+ "image/gif",
21
+ "image/jpeg",
22
+ "image/png",
23
+ "image/tiff",
24
+ "image/vnd.microsoft.icon",
25
+ "image/webp",
26
+ // Audio
27
+ "audio/3gpp",
28
+ "audio/aac",
29
+ "audio/basic",
30
+ "audio/mpeg",
31
+ "audio/ogg",
32
+ "audio/wavaudio/webm",
33
+ "audio/x-aiff",
34
+ "audio/x-midi",
35
+ "audio/x-wav",
36
+ // Video
37
+ "video/3gpp",
38
+ "video/mp2t",
39
+ "video/mpeg",
40
+ "video/ogg",
41
+ "video/quicktime",
42
+ "video/webm",
43
+ "video/x-msvideo",
44
+ // Archives
45
+ "application/java-archive",
46
+ "application/vnd.apple.installer+xml",
47
+ "application/x-7z-compressed",
48
+ "application/x-apple-diskimage",
49
+ "application/x-bzip",
50
+ "application/x-bzip2",
51
+ "application/x-gzip",
52
+ "application/x-java-archive",
53
+ "application/x-rar-compressed",
54
+ "application/x-tar",
55
+ "application/x-zip",
56
+ "application/zip",
57
+ ]);
58
+ export function isBinaryContentType(contentType) {
59
+ if (!contentType)
60
+ return false;
61
+ const value = contentType?.split(";")[0] ?? "";
62
+ return commonBinaryMimeTypes.has(value);
63
+ }
@@ -0,0 +1,23 @@
1
+ import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, APIGatewayProxyEvent, APIGatewayProxyResult, CloudFrontRequestEvent, CloudFrontRequestResult } from "aws-lambda";
2
+ export type InternalEvent = {
3
+ readonly type: "v1" | "v2" | "cf";
4
+ readonly method: string;
5
+ readonly rawPath: string;
6
+ readonly url: string;
7
+ readonly body: Buffer;
8
+ readonly headers: Record<string, string>;
9
+ readonly remoteAddress: string;
10
+ };
11
+ type InternalResult = {
12
+ readonly type: "v1" | "v2" | "cf";
13
+ statusCode: number;
14
+ headers: Record<string, string | string[]>;
15
+ body: string;
16
+ isBase64Encoded: boolean;
17
+ };
18
+ export declare function isAPIGatewayProxyEventV2(event: any): event is APIGatewayProxyEventV2;
19
+ export declare function isAPIGatewayProxyEvent(event: any): event is APIGatewayProxyEvent;
20
+ export declare function isCloudFrontRequestEvent(event: any): event is CloudFrontRequestEvent;
21
+ export declare function convertFrom(event: APIGatewayProxyEventV2 | APIGatewayProxyEvent | CloudFrontRequestEvent): InternalEvent;
22
+ export declare function convertTo(result: InternalResult): APIGatewayProxyResultV2 | APIGatewayProxyResult | CloudFrontRequestResult;
23
+ export {};
@@ -0,0 +1,209 @@
1
+ import { debug } from "./logger.js";
2
+ export function isAPIGatewayProxyEventV2(event) {
3
+ return event.version === "2.0";
4
+ }
5
+ export function isAPIGatewayProxyEvent(event) {
6
+ return event.version === undefined && !isCloudFrontRequestEvent(event);
7
+ }
8
+ export function isCloudFrontRequestEvent(event) {
9
+ return event.Records !== undefined;
10
+ }
11
+ export function convertFrom(event) {
12
+ if (isCloudFrontRequestEvent(event)) {
13
+ return convertFromCloudFrontRequestEvent(event);
14
+ }
15
+ else if (isAPIGatewayProxyEventV2(event)) {
16
+ return convertFromAPIGatewayProxyEventV2(event);
17
+ }
18
+ else if (isAPIGatewayProxyEvent(event)) {
19
+ return convertFromAPIGatewayProxyEvent(event);
20
+ }
21
+ throw new Error("Unsupported event type");
22
+ }
23
+ export function convertTo(result) {
24
+ if (result.type === "v2") {
25
+ return convertToApiGatewayProxyResultV2(result);
26
+ }
27
+ else if (result.type === "v1") {
28
+ return convertToApiGatewayProxyResult(result);
29
+ }
30
+ else if (result.type === "cf") {
31
+ return convertToCloudFrontRequestResult(result);
32
+ }
33
+ throw new Error("Unsupported event type");
34
+ }
35
+ function convertFromAPIGatewayProxyEvent(event) {
36
+ const { path, body, httpMethod, requestContext, isBase64Encoded } = event;
37
+ return {
38
+ type: "v1",
39
+ method: httpMethod,
40
+ rawPath: path,
41
+ url: path + normalizeAPIGatewayProxyEventQueryParams(event),
42
+ body: Buffer.from(body ?? "", isBase64Encoded ? "base64" : "utf8"),
43
+ headers: normalizeAPIGatewayProxyEventHeaders(event),
44
+ remoteAddress: requestContext.identity.sourceIp,
45
+ };
46
+ }
47
+ function convertFromAPIGatewayProxyEventV2(event) {
48
+ const { rawPath, rawQueryString, requestContext } = event;
49
+ return {
50
+ type: "v2",
51
+ method: requestContext.http.method,
52
+ rawPath,
53
+ url: rawPath + (rawQueryString ? `?${rawQueryString}` : ""),
54
+ body: normalizeAPIGatewayProxyEventV2Body(event),
55
+ headers: normalizeAPIGatewayProxyEventV2Headers(event),
56
+ remoteAddress: requestContext.http.sourceIp,
57
+ };
58
+ }
59
+ function convertFromCloudFrontRequestEvent(event) {
60
+ const { method, uri, querystring, body, headers, clientIp } = event.Records[0].cf.request;
61
+ return {
62
+ type: "cf",
63
+ method,
64
+ rawPath: uri,
65
+ url: uri + (querystring ? `?${querystring}` : ""),
66
+ body: Buffer.from(body?.data ?? "", body?.encoding === "base64" ? "base64" : "utf8"),
67
+ headers: normalizeCloudFrontRequestEventHeaders(headers),
68
+ remoteAddress: clientIp,
69
+ };
70
+ }
71
+ function convertToApiGatewayProxyResult(result) {
72
+ const headers = {};
73
+ const multiValueHeaders = {};
74
+ Object.entries(result.headers).forEach(([key, value]) => {
75
+ if (Array.isArray(value)) {
76
+ multiValueHeaders[key] = value;
77
+ }
78
+ else {
79
+ if (value === null) {
80
+ headers[key] = "";
81
+ return;
82
+ }
83
+ headers[key] = value;
84
+ }
85
+ });
86
+ const response = {
87
+ statusCode: result.statusCode,
88
+ headers,
89
+ body: result.body,
90
+ isBase64Encoded: result.isBase64Encoded,
91
+ multiValueHeaders,
92
+ };
93
+ debug(response);
94
+ return response;
95
+ }
96
+ function convertToApiGatewayProxyResultV2(result) {
97
+ const headers = {};
98
+ Object.entries(result.headers)
99
+ .filter(([key]) => key.toLowerCase() !== "set-cookie")
100
+ .forEach(([key, value]) => {
101
+ if (value === null) {
102
+ headers[key] = "";
103
+ return;
104
+ }
105
+ headers[key] = Array.isArray(value) ? value.join(", ") : value.toString();
106
+ });
107
+ const response = {
108
+ statusCode: result.statusCode,
109
+ headers,
110
+ cookies: result.headers["set-cookie"],
111
+ body: result.body,
112
+ isBase64Encoded: result.isBase64Encoded,
113
+ };
114
+ debug(response);
115
+ return response;
116
+ }
117
+ function convertToCloudFrontRequestResult(result) {
118
+ const headers = {};
119
+ Object.entries(result.headers)
120
+ .filter(([key]) => key.toLowerCase() !== "content-length")
121
+ .forEach(([key, value]) => {
122
+ headers[key] = [
123
+ ...(headers[key] || []),
124
+ ...(Array.isArray(value)
125
+ ? value.map((v) => ({ key, value: v }))
126
+ : [{ key, value: value.toString() }]),
127
+ ];
128
+ });
129
+ const response = {
130
+ status: result.statusCode.toString(),
131
+ statusDescription: "OK",
132
+ headers,
133
+ bodyEncoding: result.isBase64Encoded ? "base64" : "text",
134
+ body: result.body,
135
+ };
136
+ debug(response);
137
+ return response;
138
+ }
139
+ function normalizeAPIGatewayProxyEventV2Headers(event) {
140
+ const { headers: rawHeaders, cookies } = event;
141
+ const headers = {};
142
+ if (Array.isArray(cookies)) {
143
+ headers["cookie"] = cookies.join("; ");
144
+ }
145
+ for (const [key, value] of Object.entries(rawHeaders || {})) {
146
+ headers[key.toLowerCase()] = value;
147
+ }
148
+ return headers;
149
+ }
150
+ function normalizeAPIGatewayProxyEventV2Body(event) {
151
+ const { body, isBase64Encoded } = event;
152
+ if (Buffer.isBuffer(body)) {
153
+ return body;
154
+ }
155
+ else if (typeof body === "string") {
156
+ return Buffer.from(body, isBase64Encoded ? "base64" : "utf8");
157
+ }
158
+ else if (typeof body === "object") {
159
+ return Buffer.from(JSON.stringify(body));
160
+ }
161
+ return Buffer.from("", "utf8");
162
+ }
163
+ function normalizeAPIGatewayProxyEventQueryParams(event) {
164
+ const params = new URLSearchParams();
165
+ if (event.multiValueQueryStringParameters) {
166
+ for (const [key, value] of Object.entries(event.multiValueQueryStringParameters)) {
167
+ if (value !== undefined) {
168
+ for (const v of value) {
169
+ params.append(key, v);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ if (event.queryStringParameters) {
175
+ for (const [key, value] of Object.entries(event.queryStringParameters)) {
176
+ if (value !== undefined) {
177
+ params.append(key, value);
178
+ }
179
+ }
180
+ }
181
+ const value = params.toString();
182
+ return value ? `?${value}` : "";
183
+ }
184
+ function normalizeAPIGatewayProxyEventHeaders(event) {
185
+ event.multiValueHeaders;
186
+ const headers = {};
187
+ for (const [key, values] of Object.entries(event.multiValueHeaders)) {
188
+ if (values) {
189
+ headers[key.toLowerCase()] = values.join(",");
190
+ }
191
+ }
192
+ for (const [key, value] of Object.entries(event.headers)) {
193
+ if (value) {
194
+ headers[key.toLowerCase()] = value;
195
+ }
196
+ }
197
+ return headers;
198
+ }
199
+ function normalizeCloudFrontRequestEventHeaders(rawHeaders) {
200
+ const headers = {};
201
+ for (const [key, values] of Object.entries(rawHeaders)) {
202
+ for (const { value } of values) {
203
+ if (value) {
204
+ headers[key.toLowerCase()] = value;
205
+ }
206
+ }
207
+ }
208
+ return headers;
209
+ }
@@ -0,0 +1,2 @@
1
+ import type { APIGatewayProxyEventV2, APIGatewayProxyEvent, CloudFrontRequestEvent } from "aws-lambda";
2
+ export declare function handler(event: APIGatewayProxyEventV2 | CloudFrontRequestEvent | APIGatewayProxyEvent): Promise<import("aws-lambda").APIGatewayProxyResultV2 | import("aws-lambda").APIGatewayProxyResult | import("aws-lambda").CloudFrontRequestResult>;
@@ -0,0 +1,101 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ // @ts-ignore Generated next to the server output by `builder.generateServerInstance`
4
+ import { server } from "../server.js";
5
+ // @ts-ignore Written by the adapter when it runs
6
+ import prerenderedFiles from "./prerendered-file-list.js";
7
+ import { convertFrom, convertTo } from "./event-mapper.js";
8
+ import { debug } from "./logger.js";
9
+ import { isBinaryContentType } from "./binary.js";
10
+ await server.init({ env: process.env });
11
+ export async function handler(event) {
12
+ debug("event", event);
13
+ // Parse Lambda event
14
+ const internalEvent = convertFrom(event);
15
+ // Set correct host header
16
+ if (internalEvent.headers["x-forwarded-host"]) {
17
+ internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
18
+ }
19
+ // Check request is for prerendered file
20
+ if (internalEvent.method === "GET") {
21
+ const filePath = isPrerenderedFile(internalEvent.rawPath);
22
+ if (filePath) {
23
+ return internalEvent.type === "cf"
24
+ ? formatCloudFrontPrerenderedResponse(event, filePath)
25
+ : formatAPIGatewayPrerenderedResponse(internalEvent, filePath);
26
+ }
27
+ }
28
+ // Process request
29
+ const requestUrl = `https://${internalEvent.headers.host}${internalEvent.url}`;
30
+ const requestProps = {
31
+ method: internalEvent.method,
32
+ headers: internalEvent.headers,
33
+ body: ["GET", "HEAD"].includes(internalEvent.method)
34
+ ? undefined
35
+ : new Uint8Array(internalEvent.body),
36
+ };
37
+ debug("request", requestUrl, requestProps);
38
+ const request = new Request(requestUrl, requestProps);
39
+ const response = await server.respond(request, {
40
+ getClientAddress: () => internalEvent.remoteAddress,
41
+ });
42
+ debug("response", response);
43
+ //Parse the response into lambda proxy response
44
+ if (response) {
45
+ const headers = {};
46
+ response.headers.forEach((value, key) => {
47
+ headers[key] = headers[key] || [];
48
+ headers[key].push(value);
49
+ });
50
+ const isBase64Encoded = isBinaryContentType(Array.isArray(headers["content-type"])
51
+ ? headers["content-type"][0]
52
+ : headers["content-type"]);
53
+ const body = isBase64Encoded
54
+ ? Buffer.from(await response.arrayBuffer()).toString("base64")
55
+ : await response.text();
56
+ return convertTo({
57
+ type: internalEvent.type,
58
+ statusCode: response.status,
59
+ headers,
60
+ isBase64Encoded,
61
+ body,
62
+ });
63
+ }
64
+ return {
65
+ statusCode: 404,
66
+ body: "Not found.",
67
+ };
68
+ }
69
+ function isPrerenderedFile(uri) {
70
+ // remove leading and trailing slashes
71
+ uri = uri.replace(/^\/|\/$/g, "");
72
+ if (uri === "") {
73
+ return prerenderedFiles.includes("index.html") ? "index.html" : undefined;
74
+ }
75
+ if (prerenderedFiles.includes(uri)) {
76
+ return uri;
77
+ }
78
+ if (prerenderedFiles.includes(uri + "/index.html")) {
79
+ return uri + "/index.html";
80
+ }
81
+ if (prerenderedFiles.includes(uri + ".html")) {
82
+ return uri + ".html";
83
+ }
84
+ }
85
+ function formatCloudFrontPrerenderedResponse(event, filePath) {
86
+ const request = event.Records[0].cf.request;
87
+ request.uri = `/${filePath}`;
88
+ return request;
89
+ }
90
+ function formatAPIGatewayPrerenderedResponse(internalEvent, filePath) {
91
+ return convertTo({
92
+ type: internalEvent.type,
93
+ statusCode: 200,
94
+ headers: {
95
+ "content-type": "text/html",
96
+ "cache-control": "public, max-age=0, s-maxage=31536000, must-revalidate",
97
+ },
98
+ isBase64Encoded: false,
99
+ body: fs.readFileSync(path.join("prerendered", filePath), "utf8"),
100
+ });
101
+ }
@@ -0,0 +1 @@
1
+ export declare function debug(...args: any[]): void;
@@ -0,0 +1,5 @@
1
+ export function debug(...args) {
2
+ if (process.env.SST_DEBUG) {
3
+ console.log(...args);
4
+ }
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { Adapter } from "@sveltejs/kit";
2
+ export default function (): Adapter;
package/dist/index.js ADDED
@@ -0,0 +1,64 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __dirname = fileURLToPath(new URL(".", import.meta.url));
5
+ export default function () {
6
+ return {
7
+ name: "svelte-kit-sst",
8
+ async adapt(builder) {
9
+ const out = path.join(".svelte-kit", "svelte-kit-sst");
10
+ const clientDir = path.join(out, "client");
11
+ const serverDir = path.join(out, "server");
12
+ const prerenderedDir = path.join(out, "prerendered");
13
+ // Cleanup output folder
14
+ fs.rmSync(out, { force: true, recursive: true });
15
+ fs.mkdirSync(clientDir, { recursive: true });
16
+ fs.mkdirSync(prerenderedDir, { recursive: true });
17
+ // Create static output
18
+ builder.log.minor("Copying assets...");
19
+ builder.writeClient(clientDir);
20
+ const prerenderedFiles = builder.writePrerendered(prerenderedDir);
21
+ // Create Lambda function. Both branches leave a `server.js` in the server
22
+ // folder that exports `server`, which is all the Lambda handler imports.
23
+ builder.log.minor("Generating server function...");
24
+ if (typeof builder.generateServerInstance === "function") {
25
+ // SvelteKit 3 writes the server instance next to its own server output.
26
+ // Generate it there, then copy everything over.
27
+ const kitServerDir = builder.getServerDirectory();
28
+ builder.generateServerInstance(path.join(kitServerDir, "server.js"));
29
+ builder.copy(kitServerDir, serverDir);
30
+ }
31
+ else {
32
+ // SvelteKit 2 has no `generateServerInstance`. Copy the server output
33
+ // and build the instance from the `Server` class and manifest it wrote.
34
+ // Install Kit 2's polyfills first, as the handler did before Kit 3:
35
+ // they set `crypto` and `File` on Node versions that lack them.
36
+ builder.writeServer(serverDir);
37
+ fs.writeFileSync(path.join(serverDir, "server.js"), [
38
+ `import { installPolyfills } from "@sveltejs/kit/node/polyfills";`,
39
+ `import { Server } from "./index.js";`,
40
+ `import { manifest } from "./manifest.js";`,
41
+ ``,
42
+ `installPolyfills();`,
43
+ ``,
44
+ `export const server = new Server(manifest);`,
45
+ ``,
46
+ ].join("\n"));
47
+ }
48
+ // copy over handler files in server handler folder
49
+ builder.copy(path.join(__dirname, "handler"), path.join(serverDir, "lambda-handler"));
50
+ // save a list of files in server handler folder
51
+ fs.writeFileSync(path.join(serverDir, "lambda-handler", "prerendered-file-list.js"), `export default ${JSON.stringify(prerenderedFiles)}`);
52
+ },
53
+ supports: {
54
+ // The function only contains the server code and prerendered pages. The
55
+ // client assets are served from S3, so `read` can't open them.
56
+ read: ({ route }) => {
57
+ throw new Error(`svelte-kit-sst doesn't support \`read\` from '$app/server' (used by ${route.id}). ` +
58
+ "Client assets are served from S3 and aren't included in the Lambda function.");
59
+ },
60
+ // Wrapping the entrypoint for instrumentation isn't implemented yet.
61
+ instrumentation: () => false,
62
+ },
63
+ };
64
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@sst-community/svelte-kit-sst",
3
+ "description": "Adapter for SvelteKit apps to work on AWS Lambda and AWS Lambda@Edge.",
4
+ "version": "3.0.0",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": {
8
+ "name": "SST",
9
+ "url": "https://sst.dev"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/sst-community/sst.git",
14
+ "directory": "packages/svelte-kit-sst"
15
+ },
16
+ "keywords": [
17
+ "svelte",
18
+ "svelte-kit",
19
+ "svelte-kit-adapter"
20
+ ],
21
+ "bugs": "https://github.com/sst-community/sst/issues",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "CHANGELOG.md"
32
+ ],
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "scripts": {
37
+ "build": "rm -rf dist && tsc",
38
+ "prepack": "npm run build",
39
+ "test": "npm run build && node --test \"test/*.test.mjs\""
40
+ },
41
+ "peerDependencies": {
42
+ "@sveltejs/kit": "^2.0.0 || ^3.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@sveltejs/kit": "3.0.0",
46
+ "@types/aws-lambda": "8.10.162",
47
+ "@types/node": "24.19.1",
48
+ "esbuild": "0.27.2",
49
+ "typescript": "6.0.3"
50
+ }
51
+ }